001: /*
002: * Copyright (c) 2001-2007, Jean Tessier
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * * Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * * Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in the
014: * documentation and/or other materials provided with the distribution.
015: *
016: * * Neither the name of Jean Tessier nor the names of his contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032:
033: package com.jeantessier.classreader;
034:
035: public class Instruction implements Visitable {
036: private static String[] opcode = new String[256];
037: private static int[] length = new int[256];
038:
039: static {
040: opcode[0x00] = "nop";
041: length[0x00] = 1;
042: opcode[0x01] = "aconst_null";
043: length[0x01] = 1;
044: opcode[0x02] = "iconst_m1";
045: length[0x02] = 1;
046: opcode[0x03] = "iconst_0";
047: length[0x03] = 1;
048: opcode[0x04] = "iconst_1";
049: length[0x04] = 1;
050: opcode[0x05] = "iconst_2";
051: length[0x05] = 1;
052: opcode[0x06] = "iconst_3";
053: length[0x06] = 1;
054: opcode[0x07] = "iconst_4";
055: length[0x07] = 1;
056: opcode[0x08] = "iconst_5";
057: length[0x08] = 1;
058: opcode[0x09] = "lconst_0";
059: length[0x09] = 1;
060: opcode[0x0a] = "lconst_1";
061: length[0x0a] = 1;
062: opcode[0x0b] = "fconst_0";
063: length[0x0b] = 1;
064: opcode[0x0c] = "fconst_1";
065: length[0x0c] = 1;
066: opcode[0x0d] = "fconst_2";
067: length[0x0d] = 1;
068: opcode[0x0e] = "dconst_0";
069: length[0x0e] = 1;
070: opcode[0x0f] = "dconst_1";
071: length[0x0f] = 1;
072:
073: opcode[0x10] = "bipush";
074: length[0x10] = 2;
075: opcode[0x11] = "sipush";
076: length[0x11] = 3;
077: opcode[0x12] = "ldc";
078: length[0x12] = 2;
079: opcode[0x13] = "ldc_w";
080: length[0x13] = 3;
081: opcode[0x14] = "ldc2_w";
082: length[0x14] = 3;
083: opcode[0x15] = "iload";
084: length[0x15] = 2;
085: opcode[0x16] = "lload";
086: length[0x16] = 2;
087: opcode[0x17] = "fload";
088: length[0x17] = 2;
089: opcode[0x18] = "dload";
090: length[0x18] = 2;
091: opcode[0x19] = "aload";
092: length[0x19] = 2;
093: opcode[0x1a] = "iload_0";
094: length[0x1a] = 1;
095: opcode[0x1b] = "iload_1";
096: length[0x1b] = 1;
097: opcode[0x1c] = "iload_2";
098: length[0x1c] = 1;
099: opcode[0x1d] = "iload_3";
100: length[0x1d] = 1;
101: opcode[0x1e] = "lload_0";
102: length[0x1e] = 1;
103: opcode[0x1f] = "lload_1";
104: length[0x1f] = 1;
105:
106: opcode[0x20] = "lload_2";
107: length[0x20] = 1;
108: opcode[0x21] = "lload_3";
109: length[0x21] = 1;
110: opcode[0x22] = "fload_0";
111: length[0x22] = 1;
112: opcode[0x23] = "fload_1";
113: length[0x23] = 1;
114: opcode[0x24] = "fload_2";
115: length[0x24] = 1;
116: opcode[0x25] = "fload_3";
117: length[0x25] = 1;
118: opcode[0x26] = "dload_0";
119: length[0x26] = 1;
120: opcode[0x27] = "dload_1";
121: length[0x27] = 1;
122: opcode[0x28] = "dload_2";
123: length[0x28] = 1;
124: opcode[0x29] = "dload_3";
125: length[0x29] = 1;
126: opcode[0x2a] = "aload_0";
127: length[0x2a] = 1;
128: opcode[0x2b] = "aload_1";
129: length[0x2b] = 1;
130: opcode[0x2c] = "aload_2";
131: length[0x2c] = 1;
132: opcode[0x2d] = "aload_3";
133: length[0x2d] = 1;
134: opcode[0x2e] = "iaload";
135: length[0x2e] = 1;
136: opcode[0x2f] = "laload";
137: length[0x2f] = 1;
138:
139: opcode[0x30] = "faload";
140: length[0x30] = 1;
141: opcode[0x31] = "daload";
142: length[0x31] = 1;
143: opcode[0x32] = "aaload";
144: length[0x32] = 1;
145: opcode[0x33] = "baload";
146: length[0x33] = 1;
147: opcode[0x34] = "caload";
148: length[0x34] = 1;
149: opcode[0x35] = "saload";
150: length[0x35] = 1;
151: opcode[0x36] = "istore";
152: length[0x36] = 2;
153: opcode[0x37] = "lstore";
154: length[0x37] = 2;
155: opcode[0x38] = "fstore";
156: length[0x38] = 2;
157: opcode[0x39] = "dstore";
158: length[0x39] = 2;
159: opcode[0x3a] = "astore";
160: length[0x3a] = 2;
161: opcode[0x3b] = "istore_0";
162: length[0x3b] = 1;
163: opcode[0x3c] = "istore_1";
164: length[0x3c] = 1;
165: opcode[0x3d] = "istore_2";
166: length[0x3d] = 1;
167: opcode[0x3e] = "istore_3";
168: length[0x3e] = 1;
169: opcode[0x3f] = "lstore_0";
170: length[0x3f] = 1;
171:
172: opcode[0x40] = "lstore_1";
173: length[0x40] = 1;
174: opcode[0x41] = "lstore_2";
175: length[0x41] = 1;
176: opcode[0x42] = "lstore_3";
177: length[0x42] = 1;
178: opcode[0x43] = "fstore_0";
179: length[0x43] = 1;
180: opcode[0x44] = "fstore_1";
181: length[0x44] = 1;
182: opcode[0x45] = "fstore_2";
183: length[0x45] = 1;
184: opcode[0x46] = "fstore_3";
185: length[0x46] = 1;
186: opcode[0x47] = "dstore_0";
187: length[0x47] = 1;
188: opcode[0x48] = "dstore_1";
189: length[0x48] = 1;
190: opcode[0x49] = "dstore_2";
191: length[0x49] = 1;
192: opcode[0x4a] = "dstore_3";
193: length[0x4a] = 1;
194: opcode[0x4b] = "astore_0";
195: length[0x4b] = 1;
196: opcode[0x4c] = "astore_1";
197: length[0x4c] = 1;
198: opcode[0x4d] = "astore_2";
199: length[0x4d] = 1;
200: opcode[0x4e] = "astore_3";
201: length[0x4e] = 1;
202: opcode[0x4f] = "iastore";
203: length[0x4f] = 1;
204:
205: opcode[0x50] = "lastore";
206: length[0x50] = 1;
207: opcode[0x51] = "fastore";
208: length[0x51] = 1;
209: opcode[0x52] = "dastore";
210: length[0x52] = 1;
211: opcode[0x53] = "aastore";
212: length[0x53] = 1;
213: opcode[0x54] = "bastore";
214: length[0x54] = 1;
215: opcode[0x55] = "castore";
216: length[0x55] = 1;
217: opcode[0x56] = "sastore";
218: length[0x56] = 1;
219: opcode[0x57] = "pop";
220: length[0x57] = 1;
221: opcode[0x58] = "pop2";
222: length[0x58] = 1;
223: opcode[0x59] = "dup";
224: length[0x59] = 1;
225: opcode[0x5a] = "dup_x1";
226: length[0x5a] = 1;
227: opcode[0x5b] = "dup_x2";
228: length[0x5b] = 1;
229: opcode[0x5c] = "dup2";
230: length[0x5c] = 1;
231: opcode[0x5d] = "dup2_x1";
232: length[0x5d] = 1;
233: opcode[0x5e] = "dup2_x2";
234: length[0x5e] = 1;
235: opcode[0x5f] = "swap";
236: length[0x5f] = 1;
237:
238: opcode[0x60] = "iadd";
239: length[0x60] = 1;
240: opcode[0x61] = "ladd";
241: length[0x61] = 1;
242: opcode[0x62] = "fadd";
243: length[0x62] = 1;
244: opcode[0x63] = "dadd";
245: length[0x63] = 1;
246: opcode[0x64] = "isub";
247: length[0x64] = 1;
248: opcode[0x65] = "lsub";
249: length[0x65] = 1;
250: opcode[0x66] = "fsub";
251: length[0x66] = 1;
252: opcode[0x67] = "dsub";
253: length[0x67] = 1;
254: opcode[0x68] = "imul";
255: length[0x68] = 1;
256: opcode[0x69] = "lmul";
257: length[0x69] = 1;
258: opcode[0x6a] = "fmul";
259: length[0x6a] = 1;
260: opcode[0x6b] = "dmul";
261: length[0x6b] = 1;
262: opcode[0x6c] = "idiv";
263: length[0x6c] = 1;
264: opcode[0x6d] = "ldiv";
265: length[0x6d] = 1;
266: opcode[0x6e] = "fdiv";
267: length[0x6e] = 1;
268: opcode[0x6f] = "ddiv";
269: length[0x6f] = 1;
270:
271: opcode[0x70] = "irem";
272: length[0x70] = 1;
273: opcode[0x71] = "lrem";
274: length[0x71] = 1;
275: opcode[0x72] = "frem";
276: length[0x72] = 1;
277: opcode[0x73] = "drem";
278: length[0x73] = 1;
279: opcode[0x74] = "ineg";
280: length[0x74] = 1;
281: opcode[0x75] = "lneg";
282: length[0x75] = 1;
283: opcode[0x76] = "fneg";
284: length[0x76] = 1;
285: opcode[0x77] = "dneg";
286: length[0x77] = 1;
287: opcode[0x78] = "ishl";
288: length[0x78] = 1;
289: opcode[0x79] = "lshl";
290: length[0x79] = 1;
291: opcode[0x7a] = "ishr";
292: length[0x7a] = 1;
293: opcode[0x7b] = "lshr";
294: length[0x7b] = 1;
295: opcode[0x7c] = "iushr";
296: length[0x7c] = 1;
297: opcode[0x7d] = "lushr";
298: length[0x7d] = 1;
299: opcode[0x7e] = "iand";
300: length[0x7e] = 1;
301: opcode[0x7f] = "land";
302: length[0x7f] = 1;
303:
304: opcode[0x80] = "ior";
305: length[0x80] = 1;
306: opcode[0x81] = "lor";
307: length[0x81] = 1;
308: opcode[0x82] = "ixor";
309: length[0x82] = 1;
310: opcode[0x83] = "lxor";
311: length[0x83] = 1;
312: opcode[0x84] = "iinc";
313: length[0x84] = 3;
314: opcode[0x85] = "i2l";
315: length[0x85] = 1;
316: opcode[0x86] = "i2f";
317: length[0x86] = 1;
318: opcode[0x87] = "i2d";
319: length[0x87] = 1;
320: opcode[0x88] = "l2i";
321: length[0x88] = 1;
322: opcode[0x89] = "l2f";
323: length[0x89] = 1;
324: opcode[0x8a] = "l2d";
325: length[0x8a] = 1;
326: opcode[0x8b] = "f2i";
327: length[0x8b] = 1;
328: opcode[0x8c] = "f2l";
329: length[0x8c] = 1;
330: opcode[0x8d] = "f2d";
331: length[0x8d] = 1;
332: opcode[0x8e] = "d2i";
333: length[0x8e] = 1;
334: opcode[0x8f] = "d2l";
335: length[0x8f] = 1;
336:
337: opcode[0x90] = "d2f";
338: length[0x90] = 1;
339: opcode[0x91] = "i2b";
340: length[0x91] = 1;
341: opcode[0x92] = "i2c";
342: length[0x92] = 1;
343: opcode[0x93] = "i2s";
344: length[0x93] = 1;
345: opcode[0x94] = "lcmp";
346: length[0x94] = 1;
347: opcode[0x95] = "fcmpl";
348: length[0x95] = 1;
349: opcode[0x96] = "fcmpg";
350: length[0x96] = 1;
351: opcode[0x97] = "dcmpl";
352: length[0x97] = 1;
353: opcode[0x98] = "dcmpg";
354: length[0x98] = 1;
355: opcode[0x99] = "ifeq";
356: length[0x99] = 3;
357: opcode[0x9a] = "ifne";
358: length[0x9a] = 3;
359: opcode[0x9b] = "iflt";
360: length[0x9b] = 3;
361: opcode[0x9c] = "ifge";
362: length[0x9c] = 3;
363: opcode[0x9d] = "ifgt";
364: length[0x9d] = 3;
365: opcode[0x9e] = "ifle";
366: length[0x9e] = 3;
367: opcode[0x9f] = "if_icmpeq";
368: length[0x9f] = 3;
369:
370: opcode[0xa0] = "if_icmpne";
371: length[0xa0] = 3;
372: opcode[0xa1] = "if_icmplt";
373: length[0xa1] = 3;
374: opcode[0xa2] = "if_icmpge";
375: length[0xa2] = 3;
376: opcode[0xa3] = "if_icmpgt";
377: length[0xa3] = 3;
378: opcode[0xa4] = "if_icmple";
379: length[0xa4] = 3;
380: opcode[0xa5] = "if_acmpeq";
381: length[0xa5] = 3;
382: opcode[0xa6] = "if_acmpne";
383: length[0xa6] = 3;
384: opcode[0xa7] = "goto";
385: length[0xa7] = 3;
386: opcode[0xa8] = "jsr";
387: length[0xa8] = 3;
388: opcode[0xa9] = "ret";
389: length[0xa9] = 2;
390: opcode[0xaa] = "tableswitch";
391: length[0xaa] = -1;
392: opcode[0xab] = "lookupswitch";
393: length[0xab] = -1;
394: opcode[0xac] = "ireturn";
395: length[0xac] = 1;
396: opcode[0xad] = "lreturn";
397: length[0xad] = 1;
398: opcode[0xae] = "freturn";
399: length[0xae] = 1;
400: opcode[0xaf] = "dreturn";
401: length[0xaf] = 1;
402:
403: opcode[0xb0] = "areturn";
404: length[0xb0] = 1;
405: opcode[0xb1] = "return";
406: length[0xb1] = 1;
407: opcode[0xb2] = "getstatic";
408: length[0xb2] = 3;
409: opcode[0xb3] = "putstatic";
410: length[0xb3] = 3;
411: opcode[0xb4] = "getfield";
412: length[0xb4] = 3;
413: opcode[0xb5] = "putfield";
414: length[0xb5] = 3;
415: opcode[0xb6] = "invokevirtual";
416: length[0xb6] = 3;
417: opcode[0xb7] = "invokespecial";
418: length[0xb7] = 3;
419: opcode[0xb8] = "invokestatic";
420: length[0xb8] = 3;
421: opcode[0xb9] = "invokeinterface";
422: length[0xb9] = 5;
423: opcode[0xba] = "invokedynamic";
424: length[0xba] = 3;
425: opcode[0xbb] = "new";
426: length[0xbb] = 3;
427: opcode[0xbc] = "newarray";
428: length[0xbc] = 2;
429: opcode[0xbd] = "anewarray";
430: length[0xbd] = 3;
431: opcode[0xbe] = "arraylength";
432: length[0xbe] = 1;
433: opcode[0xbf] = "athrow";
434: length[0xbf] = 1;
435:
436: opcode[0xc0] = "checkcast";
437: length[0xc0] = 3;
438: opcode[0xc1] = "instanceof";
439: length[0xc1] = 3;
440: opcode[0xc2] = "monitorenter";
441: length[0xc2] = 1;
442: opcode[0xc3] = "monitorexit";
443: length[0xc3] = 1;
444: opcode[0xc4] = "wide";
445: length[0xc4] = -1;
446: opcode[0xc5] = "multianewarray";
447: length[0xc5] = 4;
448: opcode[0xc6] = "ifnull";
449: length[0xc6] = 3;
450: opcode[0xc7] = "ifnonnull";
451: length[0xc7] = 3;
452: opcode[0xc8] = "goto_w";
453: length[0xc8] = 5;
454: opcode[0xc9] = "jsr_w";
455: length[0xc9] = 5;
456: opcode[0xca] = "breakpoint";
457: length[0xca] = 1;
458: opcode[0xcb] = "xxxundefinedxxx";
459: length[0xcb] = 1;
460: opcode[0xcc] = "xxxundefinedxxx";
461: length[0xcc] = 1;
462: opcode[0xcd] = "xxxundefinedxxx";
463: length[0xcd] = 1;
464: opcode[0xce] = "xxxundefinedxxx";
465: length[0xce] = 1;
466: opcode[0xcf] = "xxxundefinedxxx";
467: length[0xcf] = 1;
468:
469: opcode[0xd0] = "xxxundefinedxxx";
470: length[0xd0] = 1;
471: opcode[0xd1] = "xxxundefinedxxx";
472: length[0xd1] = 1;
473: opcode[0xd2] = "xxxundefinedxxx";
474: length[0xd2] = 1;
475: opcode[0xd3] = "xxxundefinedxxx";
476: length[0xd3] = 1;
477: opcode[0xd4] = "xxxundefinedxxx";
478: length[0xd4] = 1;
479: opcode[0xd5] = "xxxundefinedxxx";
480: length[0xd5] = 1;
481: opcode[0xd6] = "xxxundefinedxxx";
482: length[0xd6] = 1;
483: opcode[0xd7] = "xxxundefinedxxx";
484: length[0xd7] = 1;
485: opcode[0xd8] = "xxxundefinedxxx";
486: length[0xd8] = 1;
487: opcode[0xd9] = "xxxundefinedxxx";
488: length[0xd9] = 1;
489: opcode[0xda] = "xxxundefinedxxx";
490: length[0xda] = 1;
491: opcode[0xdb] = "xxxundefinedxxx";
492: length[0xdb] = 1;
493: opcode[0xdc] = "xxxundefinedxxx";
494: length[0xdc] = 1;
495: opcode[0xdd] = "xxxundefinedxxx";
496: length[0xdd] = 1;
497: opcode[0xde] = "xxxundefinedxxx";
498: length[0xde] = 1;
499: opcode[0xdf] = "xxxundefinedxxx";
500: length[0xdf] = 1;
501:
502: opcode[0xe0] = "xxxundefinedxxx";
503: length[0xe0] = 1;
504: opcode[0xe1] = "xxxundefinedxxx";
505: length[0xe1] = 1;
506: opcode[0xe2] = "xxxundefinedxxx";
507: length[0xe2] = 1;
508: opcode[0xe3] = "xxxundefinedxxx";
509: length[0xe3] = 1;
510: opcode[0xe4] = "xxxundefinedxxx";
511: length[0xe4] = 1;
512: opcode[0xe5] = "xxxundefinedxxx";
513: length[0xe5] = 1;
514: opcode[0xe6] = "xxxundefinedxxx";
515: length[0xe6] = 1;
516: opcode[0xe7] = "xxxundefinedxxx";
517: length[0xe7] = 1;
518: opcode[0xe8] = "xxxundefinedxxx";
519: length[0xe8] = 1;
520: opcode[0xe9] = "xxxundefinedxxx";
521: length[0xe9] = 1;
522: opcode[0xea] = "xxxundefinedxxx";
523: length[0xea] = 1;
524: opcode[0xeb] = "xxxundefinedxxx";
525: length[0xeb] = 1;
526: opcode[0xec] = "xxxundefinedxxx";
527: length[0xec] = 1;
528: opcode[0xed] = "xxxundefinedxxx";
529: length[0xed] = 1;
530: opcode[0xee] = "xxxundefinedxxx";
531: length[0xee] = 1;
532: opcode[0xef] = "xxxundefinedxxx";
533: length[0xef] = 1;
534:
535: opcode[0xf0] = "xxxundefinedxxx";
536: length[0xf0] = 1;
537: opcode[0xf1] = "xxxundefinedxxx";
538: length[0xf1] = 1;
539: opcode[0xf2] = "xxxundefinedxxx";
540: length[0xf2] = 1;
541: opcode[0xf3] = "xxxundefinedxxx";
542: length[0xf3] = 1;
543: opcode[0xf4] = "xxxundefinedxxx";
544: length[0xf4] = 1;
545: opcode[0xf5] = "xxxundefinedxxx";
546: length[0xf5] = 1;
547: opcode[0xf6] = "xxxundefinedxxx";
548: length[0xf6] = 1;
549: opcode[0xf7] = "xxxundefinedxxx";
550: length[0xf7] = 1;
551: opcode[0xf8] = "xxxundefinedxxx";
552: length[0xf8] = 1;
553: opcode[0xf9] = "xxxundefinedxxx";
554: length[0xf9] = 1;
555: opcode[0xfa] = "xxxundefinedxxx";
556: length[0xfa] = 1;
557: opcode[0xfb] = "xxxundefinedxxx";
558: length[0xfb] = 1;
559: opcode[0xfc] = "xxxundefinedxxx";
560: length[0xfc] = 1;
561: opcode[0xfd] = "xxxundefinedxxx";
562: length[0xfd] = 1;
563: opcode[0xfe] = "impdep1";
564: length[0xfe] = 1;
565: opcode[0xff] = "impdep2";
566: length[0xff] = 1;
567: }
568:
569: private Code_attribute code;
570: private byte[] bytecode;
571: private int start;
572:
573: public Instruction(Code_attribute code, byte[] bytecode, int start) {
574: this .code = code;
575: this .bytecode = bytecode;
576: this .start = start;
577: }
578:
579: public Code_attribute getCode() {
580: return code;
581: }
582:
583: public byte[] getBytecode() {
584: return bytecode;
585: }
586:
587: public int getStart() {
588: return start;
589: }
590:
591: public int getOpcode() {
592: return (bytecode[start] & 0xff);
593: }
594:
595: public static String getMnemonic(int instruction) {
596: return opcode[instruction];
597: }
598:
599: public String getMnemonic() {
600: String result = getMnemonic(getOpcode());
601:
602: if (getOpcode() == 0xc4 /* wide */) {
603: result += " " + getMnemonic(bytecode[start + 1] & 0xff);
604: }
605:
606: return result;
607: }
608:
609: public int getLength() {
610: int result = length[getOpcode()];
611:
612: int padding, low, high, npairs;
613:
614: switch (getOpcode()) {
615: case 0xaa:
616: // tableswitch
617: padding = 3 - (start % 4);
618: low = ((bytecode[start + padding + 5] & 0xff) << 24)
619: | ((bytecode[start + padding + 6] & 0xff) << 16)
620: | ((bytecode[start + padding + 7] & 0xff) << 8)
621: | ((bytecode[start + padding + 8] & 0xff));
622: high = ((bytecode[start + padding + 9] & 0xff) << 24)
623: | ((bytecode[start + padding + 10] & 0xff) << 16)
624: | ((bytecode[start + padding + 11] & 0xff) << 8)
625: | ((bytecode[start + padding + 12] & 0xff));
626: result = 1 + // opcode
627: padding + // padding
628: 12 + // default + low + high
629: (high - low + 1) * 4; // (high - low + 1) * offset
630: break;
631:
632: case 0xab:
633: // lookupswitch
634: padding = 3 - (start % 4);
635: npairs = ((bytecode[start + padding + 5] & 0xff) << 24)
636: | ((bytecode[start + padding + 6] & 0xff) << 16)
637: | ((bytecode[start + padding + 7] & 0xff) << 8)
638: | ((bytecode[start + padding + 8] & 0xff));
639: result = 1 + // opcode
640: padding + // padding
641: 8 + // default + npairs
642: (npairs * 8); // npairs * (match + offset)
643: break;
644:
645: case 0xc4:
646: // wide
647: if ((bytecode[start + 1] & 0xff) == 0x84 /* iinc */) {
648: result = 6;
649: } else {
650: result = 4;
651: }
652: break;
653:
654: default:
655: // Do nothing
656: break;
657: }
658:
659: return result;
660: }
661:
662: public int getIndex() {
663: int result;
664:
665: switch (getOpcode()) {
666: case 0x13: // ldc_w
667: case 0x14: // ldc2_w
668: case 0xb2: // getstatic
669: case 0xb3: // putstatic
670: case 0xb4: // getfield
671: case 0xb5: // putfield
672: case 0xb6: // invokevirtual
673: case 0xb7: // invokespecial
674: case 0xb8: // invokestatic
675: case 0xb9: // invokeinterface
676: case 0xba: // invokedynamic
677: case 0xbb: // new
678: case 0xbd: // anewarray
679: case 0xc0: // checkcast
680: case 0xc1: // instanceof
681: case 0xc5: // multianewarray
682: result = ((getBytecode()[getStart() + 1] & 0xff) << 8)
683: | (getBytecode()[getStart() + 2] & 0xff);
684: break;
685: case 0x12: // ldc
686: case 0x15: // iload
687: case 0x16: // llload
688: case 0x17: // fload
689: case 0x18: // dload
690: case 0x19: // aload
691: case 0x36: // istore
692: case 0x37: // lstore
693: case 0x38: // fstore
694: case 0x39: // dstore
695: case 0x3a: // astore
696: case 0x84: // iinc
697: case 0xa9: // ret
698: result = getBytecode()[getStart() + 1] & 0xff;
699: break;
700: case 0xc4: // wide
701: result = ((getBytecode()[getStart() + 2] & 0xff) << 8)
702: | (getBytecode()[getStart() + 3] & 0xff);
703: break;
704: default:
705: result = -1;
706: break;
707: }
708:
709: return result;
710: }
711:
712: public ConstantPoolEntry getIndexedConstantPoolEntry() {
713: ConstantPoolEntry result;
714:
715: switch (getOpcode()) {
716: case 0x12: // ldc
717: case 0x13: // ldc_w
718: case 0x14: // ldc2_w
719: case 0xb2: // getstatic
720: case 0xb3: // putstatic
721: case 0xb4: // getfield
722: case 0xb5: // putfield
723: case 0xb6: // invokevirtual
724: case 0xb7: // invokespecial
725: case 0xb8: // invokestatic
726: case 0xb9: // invokeinterface
727: case 0xba: // invokedynamic
728: case 0xbb: // new
729: case 0xbd: // anewarray
730: case 0xc0: // checkcast
731: case 0xc1: // instanceof
732: case 0xc5: // multianewarray
733: result = getCode().getClassfile().getConstantPool().get(
734: getIndex());
735: break;
736: default:
737: result = null;
738: break;
739: }
740:
741: return result;
742: }
743:
744: public int hashCode() {
745: int result = getOpcode();
746:
747: if (getIndexedConstantPoolEntry() != null) {
748: result ^= getIndexedConstantPoolEntry().hashCode();
749: } else {
750: for (int i = 1; i < getLength(); i++) {
751: result ^= bytecode[start + i];
752: }
753: }
754:
755: return result;
756: }
757:
758: public boolean equals(Object object) {
759: boolean result;
760:
761: if (this == object) {
762: result = true;
763: } else if (object == null || getClass() != object.getClass()) {
764: result = false;
765: } else {
766: Instruction other = (Instruction) object;
767: result = getOpcode() == other.getOpcode();
768:
769: ConstantPoolEntry this Entry = (getCode() != null) ? getIndexedConstantPoolEntry()
770: : null;
771: ConstantPoolEntry otherEntry = (other.getCode() != null) ? other
772: .getIndexedConstantPoolEntry()
773: : null;
774:
775: if (result && this Entry != null && otherEntry != null) {
776: result = this Entry.equals(otherEntry);
777: } else {
778: for (int i = 1; result && i < getLength(); i++) {
779: result = bytecode[start + i] == other.bytecode[other.start
780: + i];
781: }
782: }
783: }
784:
785: return result;
786: }
787:
788: public String toString() {
789: return getMnemonic();
790: }
791:
792: public void accept(Visitor visitor) {
793: visitor.visitInstruction(this);
794: }
795: }
|