KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > netbeans > modules > java > source > usages > BytecodeDecoder


1 /*
2  * The contents of this file are subject to the terms of the Common Development
3  * and Distribution License (the License). You may not use this file except in
4  * compliance with the License.
5  *
6  * You can obtain a copy of the License at http://www.netbeans.org/cddl.html
7  * or http://www.netbeans.org/cddl.txt.
8  *
9  * When distributing Covered Code, include this CDDL Header Notice in each file
10  * and include the License file at http://www.netbeans.org/cddl.txt.
11  * If applicable, add the following below the CDDL Header, with the fields
12  * enclosed by brackets [] replaced by your own identifying information:
13  * "Portions Copyrighted [year] [name of copyright owner]"
14  *
15  * The Original Software is NetBeans. The Initial Developer of the Original
16  * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
17  * Microsystems, Inc. All Rights Reserved.
18  */

19 package org.netbeans.modules.java.source.usages;
20
21 import java.util.Iterator JavaDoc;
22 import org.netbeans.modules.classfile.ByteCodes;
23
24 /**
25  *
26  * @author Petr Hrebejk
27  */

28 public class BytecodeDecoder implements Iterator JavaDoc<byte[]>, Iterable JavaDoc<byte[]> {
29
30     static final int opcodeLengths[] = {
31            1, /* nop */
32            1, /* aconst_null */
33            1, /* iconst_m1 */
34            1, /* iconst_0 */
35            1, /* iconst_1 */
36            1, /* iconst_2 */
37            1, /* iconst_3 */
38            1, /* iconst_4 */
39            1, /* iconst_5 */
40            1, /* lconst_0 */
41            1, /* lconst_1 */
42            1, /* fconst_0 */
43            1, /* fconst_1 */
44            1, /* fconst_2 */
45            1, /* dconst_0 */
46            1, /* dconst_1 */
47            2, /* bipush */
48            3, /* sipush */
49            2, /* ldc */
50            3, /* ldc_w */
51            3, /* ldc2_w */
52            2, /* iload */
53            2, /* lload */
54            2, /* fload */
55            2, /* dload */
56            2, /* aload */
57            1, /* iload_0 */
58            1, /* iload_1 */
59            1, /* iload_2 */
60            1, /* iload_3 */
61            1, /* lload_0 */
62            1, /* lload_1 */
63            1, /* lload_2 */
64            1, /* lload_3 */
65            1, /* fload_0 */
66            1, /* fload_1 */
67            1, /* fload_2 */
68            1, /* fload_3 */
69            1, /* dload_0 */
70            1, /* dload_1 */
71            1, /* dload_2 */
72            1, /* dload_3 */
73            1, /* aload_0 */
74            1, /* aload_1 */
75            1, /* aload_2 */
76            1, /* aload_3 */
77            1, /* iaload */
78            1, /* laload */
79            1, /* faload */
80            1, /* daload */
81            1, /* aaload */
82            1, /* baload */
83            1, /* caload */
84            1, /* saload */
85            2, /* istore */
86            2, /* lstore */
87            2, /* fstore */
88            2, /* dstore */
89            2, /* astore */
90            1, /* istore_0 */
91            1, /* istore_1 */
92            1, /* istore_2 */
93            1, /* istore_3 */
94            1, /* lstore_0 */
95            1, /* lstore_1 */
96            1, /* lstore_2 */
97            1, /* lstore_3 */
98            1, /* fstore_0 */
99            1, /* fstore_1 */
100            1, /* fstore_2 */
101            1, /* fstore_3 */
102            1, /* dstore_0 */
103            1, /* dstore_1 */
104            1, /* dstore_2 */
105            1, /* dstore_3 */
106            1, /* astore_0 */
107            1, /* astore_1 */
108            1, /* astore_2 */
109            1, /* astore_3 */
110            1, /* iastore */
111            1, /* lastore */
112            1, /* fastore */
113            1, /* dastore */
114            1, /* aastore */
115            1, /* bastore */
116            1, /* castore */
117            1, /* sastore */
118            1, /* pop */
119            1, /* pop2 */
120            1, /* dup */
121            1, /* dup_x1 */
122            1, /* dup_x2 */
123            1, /* dup2 */
124            1, /* dup2_x1 */
125            1, /* dup2_x2 */
126            1, /* swap */
127            1, /* iadd */
128            1, /* ladd */
129            1, /* fadd */
130            1, /* dadd */
131            1, /* isub */
132            1, /* lsub */
133            1, /* fsub */
134            1, /* dsub */
135            1, /* imul */
136            1, /* lmul */
137            1, /* fmul */
138            1, /* dmul */
139            1, /* idiv */
140            1, /* ldiv */
141            1, /* fdiv */
142            1, /* ddiv */
143            1, /* irem */
144            1, /* lrem */
145            1, /* frem */
146            1, /* drem */
147            1, /* ineg */
148            1, /* lneg */
149            1, /* fneg */
150            1, /* dneg */
151            1, /* ishl */
152            1, /* lshl */
153            1, /* ishr */
154            1, /* lshr */
155            1, /* iushr */
156            1, /* lushr */
157            1, /* iand */
158            1, /* land */
159            1, /* ior */
160            1, /* lor */
161            1, /* ixor */
162            1, /* lxor */
163            3, /* iinc */
164            1, /* i2l */
165            1, /* i2f */
166            1, /* i2d */
167            1, /* l2i */
168            1, /* l2f */
169            1, /* l2d */
170            1, /* f2i */
171            1, /* f2l */
172            1, /* f2d */
173            1, /* d2i */
174            1, /* d2l */
175            1, /* d2f */
176            1, /* i2b */
177            1, /* i2c */
178            1, /* i2s */
179            1, /* lcmp */
180            1, /* fcmpl */
181            1, /* fcmpg */
182            1, /* dcmpl */
183            1, /* dcmpg */
184            3, /* ifeq */
185            3, /* ifne */
186            3, /* iflt */
187            3, /* ifge */
188            3, /* ifgt */
189            3, /* ifle */
190            3, /* if_icmpeq */
191            3, /* if_icmpne */
192            3, /* if_icmplt */
193            3, /* if_icmpge */
194            3, /* if_icmpgt */
195            3, /* if_icmple */
196            3, /* if_acmpeq */
197            3, /* if_acmpne */
198            3, /* goto */
199            3, /* jsr */
200            2, /* ret */
201            99, /* tableswitch */
202            99, /* lookupswitch */
203            1, /* ireturn */
204            1, /* lreturn */
205            1, /* freturn */
206            1, /* dreturn */
207            1, /* areturn */
208            1, /* return */
209            3, /* getstatic */
210            3, /* putstatic */
211            3, /* getfield */
212            3, /* putfield */
213            3, /* invokevirtual */
214            3, /* invokespecial */
215            3, /* invokestatic */
216            5, /* invokeinterface */
217            0, /* xxxunusedxxx */
218            3, /* new */
219            2, /* newarray */
220            3, /* anewarray */
221            1, /* arraylength */
222            1, /* athrow */
223            3, /* checkcast */
224            3, /* instanceof */
225            1, /* monitorenter */
226            1, /* monitorexit */
227            0, /* wide */
228            4, /* multianewarray */
229            3, /* ifnull */
230            3, /* ifnonnull */
231            5, /* goto_w */
232            5, /* jsr_w */
233            1, /* breakpoint */
234            2, /* ldc_quick */
235            3, /* ldc_w_quick */
236            3, /* ldc2_w_quick */
237            3, /* getfield_quick */
238            3, /* putfield_quick */
239            3, /* getfield2_quick */
240            3, /* putfield2_quick */
241            3, /* getstatic_quick */
242            3, /* putstatic_quick */
243            3, /* getstatic2_quick */
244            3, /* putstatic2_quick */
245            3, /* invokevirtual_quick */
246            3, /* invokenonvirtual_quick */
247            3, /* invokesuper_quick */
248            3, /* invokestatic_quick */
249            5, /* invokeinterface_quick */
250            3, /* invokevirtualobject_quick */
251            3, /* invokeignored_quick */
252            3, /* new_quick */
253            3, /* anewarray_quick */
254            4, /* multianewarray_quick */
255            3, /* checkcast_quick */
256            3, /* instanceof_quick */
257            3, /* invokevirtual_quick_w */
258            3, /* getfield_quick_w */
259            3, /* putfield_quick_w */
260            1, /* nonnull_quick */
261            1, /* exitinterpreter */
262            -1,
263            -1,
264            -1,
265            -1,
266            -1,
267            -1,
268            -1,
269            -1,
270            -1,
271            -1,
272            -1,
273            -1,
274            -1,
275            -1,
276            -1,
277            -1,
278            -1,
279            -1,
280            -1,
281            -1,
282            -1,
283            -1,
284            -1,
285            -1,
286            -1,
287         };
288     
289     private byte[] code;
290     
291     int currentIndex;
292     
293     /** Creates a new instance of BytecodeDecoder */
294     public BytecodeDecoder( byte[] code ) {
295         this.code = code;
296         this.currentIndex = 0;
297     }
298     
299     
300     public Iterator JavaDoc<byte[]> iterator() {
301         return this;
302     }
303     
304     
305     
306     public boolean hasNext() {
307         if ( currentIndex < code.length ) {
308             return true;
309         }
310         if ( currentIndex != code.length ) {
311             throw new IllegalStateException JavaDoc( "Bad end " + currentIndex + " vs. " + code.length );
312         }
313         return false;
314         
315     }
316         
317     public byte[] next() {
318         int opCode = toInt( code[currentIndex]);
319         int length;
320         
321         if (opCode == 196) {
322             // wide instruction prefix
323
// either wide <opcode> byte_1 byte_2 where opcode is iload, fload, aload, lload, dload, istore, fstore, astore, lstore, dstore, or ret
324
// or wide iinc index_byte_1 index_byte_2 const_byte_1 const_byte_2
325
int wideInstruction = toInt( code[currentIndex+1]);
326             switch (wideInstruction) {
327                 case 132: //iinc
328
length = 6;
329                     break;
330                 case 21: //iload
331
case 22: //lload
332
case 23: //fload
333
case 24: //dload
334
case 25: //aload
335
case 54: //istore
336
case 55: //lstore
337
case 56: //fstore
338
case 57: //dstore
339
case 58: //astore
340
case 169: //ret
341
length = 4;
342                     break;
343                 default:
344                     throw new IllegalArgumentException JavaDoc ("Bad wide instruction at index " + currentIndex + " wide instruction " + wideInstruction);
345             }
346         }
347         else {
348             length = opcodeLengths[opCode];
349         }
350         
351         if ( length == -1 ) {
352             throw new IllegalArgumentException JavaDoc( "Bad bytecode at index " + currentIndex + " opcode " + opCode);
353         }
354         
355         if ( length == 99 ) {
356             switch ( opCode ) {
357                 case ByteCodes.bc_lookupswitch: {
358                     int padd = 4 - ( currentIndex % 4 );
359                     int start = currentIndex + padd + 4;
360                     int npairs = toInt(code[start], code[start + 1], code[start + 2], code[start + 3] );
361                     length = padd + 8 + npairs * 8;
362                     /*
363                     System.err.println("CI " + currentIndex );
364                     System.err.println("NP " + npairs );
365                    System.err.println("ST " + start );
366                      */

367                     break;
368                 }
369                 case ByteCodes.bc_tableswitch: {
370                     int padd = 4 - ( currentIndex % 4 );
371                     int start = currentIndex + padd + 4;
372                     int low = toInt(code[start], code[start + 1], code[start + 2], code[start + 3] );
373                     int high = toInt(code[start + 4], code[start + 5], code[start + 6], code[start + 7] );
374                     length = padd + 12 + (high - low + 1) * 4;
375                     
376                     /*
377                     System.err.println("CI " + currentIndex );
378                     System.err.println("ST " + start );
379                     System.err.println("CI " + currentIndex );
380                     System.err.println("LO " + low );
381                     System.err.println("HI " + high );
382                     System.err.println("PD " + padd );
383                     System.err.println("E " + (currentIndex + length) );
384                      */

385                     break;
386                 }
387                 default:
388                     throw new IllegalArgumentException JavaDoc( "Bad bytecode at index " + currentIndex );
389             }
390         }
391         
392         byte currCode[] = new byte[length];
393         for( int i = 0; i < length; i++ ) {
394             currCode[i] = code[ currentIndex + i ];
395         }
396         
397         currentIndex += length;
398         
399         return currCode;
400     }
401         
402     public void remove() {
403         throw new UnsupportedOperationException JavaDoc( "Byte code is read only" );
404     }
405     
406     static int toInt( byte b ) {
407         return ((int)b) & 0xFF;
408     }
409     
410     static int toInt( byte b1, byte b2 ) {
411         return ( (toInt(b1) << 8) | toInt(b2) );
412     }
413     
414     static int toInt( byte b1, byte b2, byte b3, byte b4 ) {
415         return (toInt(b1) << 24) | (toInt(b2) << 16) | (toInt(b3) << 8) | toInt(b4);
416     }
417  
418 }
419
Popular Tags