001: /*
002: * ProGuard -- shrinking, optimization, obfuscation, and preverification
003: * of Java bytecode.
004: *
005: * Copyright (c) 2002-2007 Eric Lafortune (eric@graphics.cornell.edu)
006: *
007: * This program is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License as published by the Free
009: * Software Foundation; either version 2 of the License, or (at your option)
010: * any later version.
011: *
012: * This program is distributed in the hope that it will be useful, but WITHOUT
013: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
014: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
015: * more details.
016: *
017: * You should have received a copy of the GNU General Public License along
018: * with this program; if not, write to the Free Software Foundation, Inc.,
019: * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
020: */
021: package proguard.classfile.instruction;
022:
023: /**
024: * This class provides methods to create and reuse Instruction objects.
025: *
026: * @author Eric Lafortune
027: */
028: public class InstructionFactory {
029: /**
030: * Creates a new Instruction from the data in the byte array, starting
031: * at the given index.
032: */
033: public static Instruction create(byte[] code, int offset) {
034: Instruction instruction;
035:
036: int index = offset;
037: byte opcode = code[index++];
038:
039: boolean wide = false;
040: if (opcode == InstructionConstants.OP_WIDE) {
041: opcode = code[index++];
042: wide = true;
043: }
044:
045: switch (opcode) {
046: // Simple instructions.
047: case InstructionConstants.OP_NOP:
048: case InstructionConstants.OP_ACONST_NULL:
049: case InstructionConstants.OP_ICONST_M1:
050: case InstructionConstants.OP_ICONST_0:
051: case InstructionConstants.OP_ICONST_1:
052: case InstructionConstants.OP_ICONST_2:
053: case InstructionConstants.OP_ICONST_3:
054: case InstructionConstants.OP_ICONST_4:
055: case InstructionConstants.OP_ICONST_5:
056: case InstructionConstants.OP_LCONST_0:
057: case InstructionConstants.OP_LCONST_1:
058: case InstructionConstants.OP_FCONST_0:
059: case InstructionConstants.OP_FCONST_1:
060: case InstructionConstants.OP_FCONST_2:
061: case InstructionConstants.OP_DCONST_0:
062: case InstructionConstants.OP_DCONST_1:
063:
064: case InstructionConstants.OP_BIPUSH:
065: case InstructionConstants.OP_SIPUSH:
066:
067: case InstructionConstants.OP_IALOAD:
068: case InstructionConstants.OP_LALOAD:
069: case InstructionConstants.OP_FALOAD:
070: case InstructionConstants.OP_DALOAD:
071: case InstructionConstants.OP_AALOAD:
072: case InstructionConstants.OP_BALOAD:
073: case InstructionConstants.OP_CALOAD:
074: case InstructionConstants.OP_SALOAD:
075:
076: case InstructionConstants.OP_IASTORE:
077: case InstructionConstants.OP_LASTORE:
078: case InstructionConstants.OP_FASTORE:
079: case InstructionConstants.OP_DASTORE:
080: case InstructionConstants.OP_AASTORE:
081: case InstructionConstants.OP_BASTORE:
082: case InstructionConstants.OP_CASTORE:
083: case InstructionConstants.OP_SASTORE:
084: case InstructionConstants.OP_POP:
085: case InstructionConstants.OP_POP2:
086: case InstructionConstants.OP_DUP:
087: case InstructionConstants.OP_DUP_X1:
088: case InstructionConstants.OP_DUP_X2:
089: case InstructionConstants.OP_DUP2:
090: case InstructionConstants.OP_DUP2_X1:
091: case InstructionConstants.OP_DUP2_X2:
092: case InstructionConstants.OP_SWAP:
093: case InstructionConstants.OP_IADD:
094: case InstructionConstants.OP_LADD:
095: case InstructionConstants.OP_FADD:
096: case InstructionConstants.OP_DADD:
097: case InstructionConstants.OP_ISUB:
098: case InstructionConstants.OP_LSUB:
099: case InstructionConstants.OP_FSUB:
100: case InstructionConstants.OP_DSUB:
101: case InstructionConstants.OP_IMUL:
102: case InstructionConstants.OP_LMUL:
103: case InstructionConstants.OP_FMUL:
104: case InstructionConstants.OP_DMUL:
105: case InstructionConstants.OP_IDIV:
106: case InstructionConstants.OP_LDIV:
107: case InstructionConstants.OP_FDIV:
108: case InstructionConstants.OP_DDIV:
109: case InstructionConstants.OP_IREM:
110: case InstructionConstants.OP_LREM:
111: case InstructionConstants.OP_FREM:
112: case InstructionConstants.OP_DREM:
113: case InstructionConstants.OP_INEG:
114: case InstructionConstants.OP_LNEG:
115: case InstructionConstants.OP_FNEG:
116: case InstructionConstants.OP_DNEG:
117: case InstructionConstants.OP_ISHL:
118: case InstructionConstants.OP_LSHL:
119: case InstructionConstants.OP_ISHR:
120: case InstructionConstants.OP_LSHR:
121: case InstructionConstants.OP_IUSHR:
122: case InstructionConstants.OP_LUSHR:
123: case InstructionConstants.OP_IAND:
124: case InstructionConstants.OP_LAND:
125: case InstructionConstants.OP_IOR:
126: case InstructionConstants.OP_LOR:
127: case InstructionConstants.OP_IXOR:
128: case InstructionConstants.OP_LXOR:
129:
130: case InstructionConstants.OP_I2L:
131: case InstructionConstants.OP_I2F:
132: case InstructionConstants.OP_I2D:
133: case InstructionConstants.OP_L2I:
134: case InstructionConstants.OP_L2F:
135: case InstructionConstants.OP_L2D:
136: case InstructionConstants.OP_F2I:
137: case InstructionConstants.OP_F2L:
138: case InstructionConstants.OP_F2D:
139: case InstructionConstants.OP_D2I:
140: case InstructionConstants.OP_D2L:
141: case InstructionConstants.OP_D2F:
142: case InstructionConstants.OP_I2B:
143: case InstructionConstants.OP_I2C:
144: case InstructionConstants.OP_I2S:
145: case InstructionConstants.OP_LCMP:
146: case InstructionConstants.OP_FCMPL:
147: case InstructionConstants.OP_FCMPG:
148: case InstructionConstants.OP_DCMPL:
149: case InstructionConstants.OP_DCMPG:
150:
151: case InstructionConstants.OP_IRETURN:
152: case InstructionConstants.OP_LRETURN:
153: case InstructionConstants.OP_FRETURN:
154: case InstructionConstants.OP_DRETURN:
155: case InstructionConstants.OP_ARETURN:
156: case InstructionConstants.OP_RETURN:
157:
158: case InstructionConstants.OP_NEWARRAY:
159: case InstructionConstants.OP_ARRAYLENGTH:
160: case InstructionConstants.OP_ATHROW:
161:
162: case InstructionConstants.OP_MONITORENTER:
163: case InstructionConstants.OP_MONITOREXIT:
164: instruction = new SimpleInstruction();
165: break;
166:
167: // Instructions with a contant pool index.
168: case InstructionConstants.OP_LDC:
169: case InstructionConstants.OP_LDC_W:
170: case InstructionConstants.OP_LDC2_W:
171:
172: case InstructionConstants.OP_GETSTATIC:
173: case InstructionConstants.OP_PUTSTATIC:
174: case InstructionConstants.OP_GETFIELD:
175: case InstructionConstants.OP_PUTFIELD:
176:
177: case InstructionConstants.OP_INVOKEVIRTUAL:
178: case InstructionConstants.OP_INVOKESPECIAL:
179: case InstructionConstants.OP_INVOKESTATIC:
180: case InstructionConstants.OP_INVOKEINTERFACE:
181:
182: case InstructionConstants.OP_NEW:
183: case InstructionConstants.OP_ANEWARRAY:
184: case InstructionConstants.OP_CHECKCAST:
185: case InstructionConstants.OP_INSTANCEOF:
186: case InstructionConstants.OP_MULTIANEWARRAY:
187: instruction = new ConstantInstruction();
188: break;
189:
190: // Instructions with a local variable index.
191: case InstructionConstants.OP_ILOAD:
192: case InstructionConstants.OP_LLOAD:
193: case InstructionConstants.OP_FLOAD:
194: case InstructionConstants.OP_DLOAD:
195: case InstructionConstants.OP_ALOAD:
196: case InstructionConstants.OP_ILOAD_0:
197: case InstructionConstants.OP_ILOAD_1:
198: case InstructionConstants.OP_ILOAD_2:
199: case InstructionConstants.OP_ILOAD_3:
200: case InstructionConstants.OP_LLOAD_0:
201: case InstructionConstants.OP_LLOAD_1:
202: case InstructionConstants.OP_LLOAD_2:
203: case InstructionConstants.OP_LLOAD_3:
204: case InstructionConstants.OP_FLOAD_0:
205: case InstructionConstants.OP_FLOAD_1:
206: case InstructionConstants.OP_FLOAD_2:
207: case InstructionConstants.OP_FLOAD_3:
208: case InstructionConstants.OP_DLOAD_0:
209: case InstructionConstants.OP_DLOAD_1:
210: case InstructionConstants.OP_DLOAD_2:
211: case InstructionConstants.OP_DLOAD_3:
212: case InstructionConstants.OP_ALOAD_0:
213: case InstructionConstants.OP_ALOAD_1:
214: case InstructionConstants.OP_ALOAD_2:
215: case InstructionConstants.OP_ALOAD_3:
216:
217: case InstructionConstants.OP_ISTORE:
218: case InstructionConstants.OP_LSTORE:
219: case InstructionConstants.OP_FSTORE:
220: case InstructionConstants.OP_DSTORE:
221: case InstructionConstants.OP_ASTORE:
222: case InstructionConstants.OP_ISTORE_0:
223: case InstructionConstants.OP_ISTORE_1:
224: case InstructionConstants.OP_ISTORE_2:
225: case InstructionConstants.OP_ISTORE_3:
226: case InstructionConstants.OP_LSTORE_0:
227: case InstructionConstants.OP_LSTORE_1:
228: case InstructionConstants.OP_LSTORE_2:
229: case InstructionConstants.OP_LSTORE_3:
230: case InstructionConstants.OP_FSTORE_0:
231: case InstructionConstants.OP_FSTORE_1:
232: case InstructionConstants.OP_FSTORE_2:
233: case InstructionConstants.OP_FSTORE_3:
234: case InstructionConstants.OP_DSTORE_0:
235: case InstructionConstants.OP_DSTORE_1:
236: case InstructionConstants.OP_DSTORE_2:
237: case InstructionConstants.OP_DSTORE_3:
238: case InstructionConstants.OP_ASTORE_0:
239: case InstructionConstants.OP_ASTORE_1:
240: case InstructionConstants.OP_ASTORE_2:
241: case InstructionConstants.OP_ASTORE_3:
242:
243: case InstructionConstants.OP_IINC:
244:
245: case InstructionConstants.OP_RET:
246: instruction = new VariableInstruction(wide);
247: break;
248:
249: // Instructions with a branch offset operand.
250: case InstructionConstants.OP_IFEQ:
251: case InstructionConstants.OP_IFNE:
252: case InstructionConstants.OP_IFLT:
253: case InstructionConstants.OP_IFGE:
254: case InstructionConstants.OP_IFGT:
255: case InstructionConstants.OP_IFLE:
256: case InstructionConstants.OP_IFICMPEQ:
257: case InstructionConstants.OP_IFICMPNE:
258: case InstructionConstants.OP_IFICMPLT:
259: case InstructionConstants.OP_IFICMPGE:
260: case InstructionConstants.OP_IFICMPGT:
261: case InstructionConstants.OP_IFICMPLE:
262: case InstructionConstants.OP_IFACMPEQ:
263: case InstructionConstants.OP_IFACMPNE:
264: case InstructionConstants.OP_GOTO:
265: case InstructionConstants.OP_JSR:
266:
267: case InstructionConstants.OP_IFNULL:
268: case InstructionConstants.OP_IFNONNULL:
269:
270: case InstructionConstants.OP_GOTO_W:
271: case InstructionConstants.OP_JSR_W:
272: instruction = new BranchInstruction();
273: break;
274:
275: // The tableswitch instruction.
276: case InstructionConstants.OP_TABLESWITCH:
277: instruction = new TableSwitchInstruction();
278: break;
279:
280: // The lookupswitch instruction.
281: case InstructionConstants.OP_LOOKUPSWITCH:
282: instruction = new LookUpSwitchInstruction();
283: break;
284:
285: default:
286: throw new IllegalArgumentException(
287: "Unknown instruction opcode [" + opcode
288: + "] at offset " + offset);
289: }
290:
291: instruction.opcode = opcode;
292:
293: instruction.readInfo(code, index);
294:
295: return instruction;
296: }
297: }
|