1 /* 2 * ProGuard -- shrinking, optimization, obfuscation, and preverification 3 * of Java bytecode. 4 * 5 * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu) 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the Free 9 * Software Foundation; either version 2 of the License, or (at your option) 10 * any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but WITHOUT 13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 15 * more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program; if not, write to the Free Software Foundation, Inc., 19 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 */ 21 package proguard.classfile.instruction; 22 23 /** 24 * This class provides methods to create and reuse Instruction objects. 25 * 26 * @author Eric Lafortune 27 */ 28 public class InstructionFactory 29 { 30 /** 31 * Creates a new Instruction from the data in the byte array, starting 32 * at the given index. 33 */ create(byte[] code, int offset)34 public static Instruction create(byte[] code, int offset) 35 { 36 Instruction instruction; 37 38 int index = offset; 39 byte opcode = code[index++]; 40 41 boolean wide = false; 42 if (opcode == InstructionConstants.OP_WIDE) 43 { 44 opcode = code[index++]; 45 wide = true; 46 } 47 48 switch (opcode) 49 { 50 // Simple instructions. 51 case InstructionConstants.OP_NOP: 52 case InstructionConstants.OP_ACONST_NULL: 53 case InstructionConstants.OP_ICONST_M1: 54 case InstructionConstants.OP_ICONST_0: 55 case InstructionConstants.OP_ICONST_1: 56 case InstructionConstants.OP_ICONST_2: 57 case InstructionConstants.OP_ICONST_3: 58 case InstructionConstants.OP_ICONST_4: 59 case InstructionConstants.OP_ICONST_5: 60 case InstructionConstants.OP_LCONST_0: 61 case InstructionConstants.OP_LCONST_1: 62 case InstructionConstants.OP_FCONST_0: 63 case InstructionConstants.OP_FCONST_1: 64 case InstructionConstants.OP_FCONST_2: 65 case InstructionConstants.OP_DCONST_0: 66 case InstructionConstants.OP_DCONST_1: 67 68 case InstructionConstants.OP_BIPUSH: 69 case InstructionConstants.OP_SIPUSH: 70 71 case InstructionConstants.OP_IALOAD: 72 case InstructionConstants.OP_LALOAD: 73 case InstructionConstants.OP_FALOAD: 74 case InstructionConstants.OP_DALOAD: 75 case InstructionConstants.OP_AALOAD: 76 case InstructionConstants.OP_BALOAD: 77 case InstructionConstants.OP_CALOAD: 78 case InstructionConstants.OP_SALOAD: 79 80 case InstructionConstants.OP_IASTORE: 81 case InstructionConstants.OP_LASTORE: 82 case InstructionConstants.OP_FASTORE: 83 case InstructionConstants.OP_DASTORE: 84 case InstructionConstants.OP_AASTORE: 85 case InstructionConstants.OP_BASTORE: 86 case InstructionConstants.OP_CASTORE: 87 case InstructionConstants.OP_SASTORE: 88 case InstructionConstants.OP_POP: 89 case InstructionConstants.OP_POP2: 90 case InstructionConstants.OP_DUP: 91 case InstructionConstants.OP_DUP_X1: 92 case InstructionConstants.OP_DUP_X2: 93 case InstructionConstants.OP_DUP2: 94 case InstructionConstants.OP_DUP2_X1: 95 case InstructionConstants.OP_DUP2_X2: 96 case InstructionConstants.OP_SWAP: 97 case InstructionConstants.OP_IADD: 98 case InstructionConstants.OP_LADD: 99 case InstructionConstants.OP_FADD: 100 case InstructionConstants.OP_DADD: 101 case InstructionConstants.OP_ISUB: 102 case InstructionConstants.OP_LSUB: 103 case InstructionConstants.OP_FSUB: 104 case InstructionConstants.OP_DSUB: 105 case InstructionConstants.OP_IMUL: 106 case InstructionConstants.OP_LMUL: 107 case InstructionConstants.OP_FMUL: 108 case InstructionConstants.OP_DMUL: 109 case InstructionConstants.OP_IDIV: 110 case InstructionConstants.OP_LDIV: 111 case InstructionConstants.OP_FDIV: 112 case InstructionConstants.OP_DDIV: 113 case InstructionConstants.OP_IREM: 114 case InstructionConstants.OP_LREM: 115 case InstructionConstants.OP_FREM: 116 case InstructionConstants.OP_DREM: 117 case InstructionConstants.OP_INEG: 118 case InstructionConstants.OP_LNEG: 119 case InstructionConstants.OP_FNEG: 120 case InstructionConstants.OP_DNEG: 121 case InstructionConstants.OP_ISHL: 122 case InstructionConstants.OP_LSHL: 123 case InstructionConstants.OP_ISHR: 124 case InstructionConstants.OP_LSHR: 125 case InstructionConstants.OP_IUSHR: 126 case InstructionConstants.OP_LUSHR: 127 case InstructionConstants.OP_IAND: 128 case InstructionConstants.OP_LAND: 129 case InstructionConstants.OP_IOR: 130 case InstructionConstants.OP_LOR: 131 case InstructionConstants.OP_IXOR: 132 case InstructionConstants.OP_LXOR: 133 134 case InstructionConstants.OP_I2L: 135 case InstructionConstants.OP_I2F: 136 case InstructionConstants.OP_I2D: 137 case InstructionConstants.OP_L2I: 138 case InstructionConstants.OP_L2F: 139 case InstructionConstants.OP_L2D: 140 case InstructionConstants.OP_F2I: 141 case InstructionConstants.OP_F2L: 142 case InstructionConstants.OP_F2D: 143 case InstructionConstants.OP_D2I: 144 case InstructionConstants.OP_D2L: 145 case InstructionConstants.OP_D2F: 146 case InstructionConstants.OP_I2B: 147 case InstructionConstants.OP_I2C: 148 case InstructionConstants.OP_I2S: 149 case InstructionConstants.OP_LCMP: 150 case InstructionConstants.OP_FCMPL: 151 case InstructionConstants.OP_FCMPG: 152 case InstructionConstants.OP_DCMPL: 153 case InstructionConstants.OP_DCMPG: 154 155 case InstructionConstants.OP_IRETURN: 156 case InstructionConstants.OP_LRETURN: 157 case InstructionConstants.OP_FRETURN: 158 case InstructionConstants.OP_DRETURN: 159 case InstructionConstants.OP_ARETURN: 160 case InstructionConstants.OP_RETURN: 161 162 case InstructionConstants.OP_NEWARRAY: 163 case InstructionConstants.OP_ARRAYLENGTH: 164 case InstructionConstants.OP_ATHROW: 165 166 case InstructionConstants.OP_MONITORENTER: 167 case InstructionConstants.OP_MONITOREXIT: 168 instruction = new SimpleInstruction(); 169 break; 170 171 // Instructions with a contant pool index. 172 case InstructionConstants.OP_LDC: 173 case InstructionConstants.OP_LDC_W: 174 case InstructionConstants.OP_LDC2_W: 175 176 case InstructionConstants.OP_GETSTATIC: 177 case InstructionConstants.OP_PUTSTATIC: 178 case InstructionConstants.OP_GETFIELD: 179 case InstructionConstants.OP_PUTFIELD: 180 181 case InstructionConstants.OP_INVOKEVIRTUAL: 182 case InstructionConstants.OP_INVOKESPECIAL: 183 case InstructionConstants.OP_INVOKESTATIC: 184 case InstructionConstants.OP_INVOKEINTERFACE: 185 case InstructionConstants.OP_INVOKEDYNAMIC: 186 187 case InstructionConstants.OP_NEW: 188 case InstructionConstants.OP_ANEWARRAY: 189 case InstructionConstants.OP_CHECKCAST: 190 case InstructionConstants.OP_INSTANCEOF: 191 case InstructionConstants.OP_MULTIANEWARRAY: 192 instruction = new ConstantInstruction(); 193 break; 194 195 // Instructions with a local variable index. 196 case InstructionConstants.OP_ILOAD: 197 case InstructionConstants.OP_LLOAD: 198 case InstructionConstants.OP_FLOAD: 199 case InstructionConstants.OP_DLOAD: 200 case InstructionConstants.OP_ALOAD: 201 case InstructionConstants.OP_ILOAD_0: 202 case InstructionConstants.OP_ILOAD_1: 203 case InstructionConstants.OP_ILOAD_2: 204 case InstructionConstants.OP_ILOAD_3: 205 case InstructionConstants.OP_LLOAD_0: 206 case InstructionConstants.OP_LLOAD_1: 207 case InstructionConstants.OP_LLOAD_2: 208 case InstructionConstants.OP_LLOAD_3: 209 case InstructionConstants.OP_FLOAD_0: 210 case InstructionConstants.OP_FLOAD_1: 211 case InstructionConstants.OP_FLOAD_2: 212 case InstructionConstants.OP_FLOAD_3: 213 case InstructionConstants.OP_DLOAD_0: 214 case InstructionConstants.OP_DLOAD_1: 215 case InstructionConstants.OP_DLOAD_2: 216 case InstructionConstants.OP_DLOAD_3: 217 case InstructionConstants.OP_ALOAD_0: 218 case InstructionConstants.OP_ALOAD_1: 219 case InstructionConstants.OP_ALOAD_2: 220 case InstructionConstants.OP_ALOAD_3: 221 222 case InstructionConstants.OP_ISTORE: 223 case InstructionConstants.OP_LSTORE: 224 case InstructionConstants.OP_FSTORE: 225 case InstructionConstants.OP_DSTORE: 226 case InstructionConstants.OP_ASTORE: 227 case InstructionConstants.OP_ISTORE_0: 228 case InstructionConstants.OP_ISTORE_1: 229 case InstructionConstants.OP_ISTORE_2: 230 case InstructionConstants.OP_ISTORE_3: 231 case InstructionConstants.OP_LSTORE_0: 232 case InstructionConstants.OP_LSTORE_1: 233 case InstructionConstants.OP_LSTORE_2: 234 case InstructionConstants.OP_LSTORE_3: 235 case InstructionConstants.OP_FSTORE_0: 236 case InstructionConstants.OP_FSTORE_1: 237 case InstructionConstants.OP_FSTORE_2: 238 case InstructionConstants.OP_FSTORE_3: 239 case InstructionConstants.OP_DSTORE_0: 240 case InstructionConstants.OP_DSTORE_1: 241 case InstructionConstants.OP_DSTORE_2: 242 case InstructionConstants.OP_DSTORE_3: 243 case InstructionConstants.OP_ASTORE_0: 244 case InstructionConstants.OP_ASTORE_1: 245 case InstructionConstants.OP_ASTORE_2: 246 case InstructionConstants.OP_ASTORE_3: 247 248 case InstructionConstants.OP_IINC: 249 250 case InstructionConstants.OP_RET: 251 instruction = new VariableInstruction(wide); 252 break; 253 254 // Instructions with a branch offset operand. 255 case InstructionConstants.OP_IFEQ: 256 case InstructionConstants.OP_IFNE: 257 case InstructionConstants.OP_IFLT: 258 case InstructionConstants.OP_IFGE: 259 case InstructionConstants.OP_IFGT: 260 case InstructionConstants.OP_IFLE: 261 case InstructionConstants.OP_IFICMPEQ: 262 case InstructionConstants.OP_IFICMPNE: 263 case InstructionConstants.OP_IFICMPLT: 264 case InstructionConstants.OP_IFICMPGE: 265 case InstructionConstants.OP_IFICMPGT: 266 case InstructionConstants.OP_IFICMPLE: 267 case InstructionConstants.OP_IFACMPEQ: 268 case InstructionConstants.OP_IFACMPNE: 269 case InstructionConstants.OP_GOTO: 270 case InstructionConstants.OP_JSR: 271 272 case InstructionConstants.OP_IFNULL: 273 case InstructionConstants.OP_IFNONNULL: 274 275 case InstructionConstants.OP_GOTO_W: 276 case InstructionConstants.OP_JSR_W: 277 instruction = new BranchInstruction(); 278 break; 279 280 // The tableswitch instruction. 281 case InstructionConstants.OP_TABLESWITCH: 282 instruction = new TableSwitchInstruction(); 283 break; 284 285 // The lookupswitch instruction. 286 case InstructionConstants.OP_LOOKUPSWITCH: 287 instruction = new LookUpSwitchInstruction(); 288 break; 289 290 default: 291 throw new IllegalArgumentException("Unknown instruction opcode ["+opcode+"] at offset "+offset); 292 } 293 294 instruction.opcode = opcode; 295 296 instruction.readInfo(code, index); 297 298 return instruction; 299 } 300 } 301