KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > objectweb > asm > commons > AnalyzerAdapter


1 /***
2  * ASM: a very small and fast Java bytecode manipulation framework
3  * Copyright (c) 2000-2005 INRIA, France Telecom
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  * notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the distribution.
14  * 3. Neither the name of the copyright holders nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
28  * THE POSSIBILITY OF SUCH DAMAGE.
29  */

30 package org.objectweb.asm.commons;
31
32 import java.util.ArrayList JavaDoc;
33 import java.util.HashMap JavaDoc;
34 import java.util.List JavaDoc;
35 import java.util.Map JavaDoc;
36
37 import org.objectweb.asm.Label;
38 import org.objectweb.asm.MethodAdapter;
39 import org.objectweb.asm.MethodVisitor;
40 import org.objectweb.asm.Opcodes;
41 import org.objectweb.asm.Type;
42
43 /**
44  * A {@link MethodAdapter} that keeps track of stack map frame changes between
45  * {@link #visitFrame(int, int, Object[], int, Object[]) visitFrame} calls. This
46  * adapter must be used with the
47  * {@link org.objectweb.asm.ClassReader#EXPAND_FRAMES} option. Each visit<i>XXX</i>
48  * instruction delegates to the next visitor in the chain, if any, and then
49  * simulates the effect of this instruction on the stack map frame, represented
50  * by {@link #locals} and {@link #stack}. The next visitor in the chain can get
51  * the state of the stack map frame <i>before</i> each instruction by reading
52  * the value of these fields in its visit<i>XXX</i> methods (this requires a
53  * reference to the AnalyzerAdapter that is before it in the chain).
54  *
55  * @author Eric Bruneton
56  */

57 public class AnalyzerAdapter extends MethodAdapter {
58
59     /**
60      * <code>List</code> of the local variable slots for current execution
61      * frame. Primitive types are represented by {@link Opcodes#TOP},
62      * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
63      * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
64      * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a
65      * two elements, the second one being TOP). Reference types are represented
66      * by String objects (representing internal names, or type descriptors for
67      * array types), and uninitialized types by Label objects (this label
68      * designates the NEW instruction that created this uninitialized value).
69      * This field is <tt>null</tt> for unreacheable instructions.
70      */

71     public List JavaDoc locals;
72
73     /**
74      * <code>List</code> of the operand stack slots for current execution
75      * frame. Primitive types are represented by {@link Opcodes#TOP},
76      * {@link Opcodes#INTEGER}, {@link Opcodes#FLOAT}, {@link Opcodes#LONG},
77      * {@link Opcodes#DOUBLE},{@link Opcodes#NULL} or
78      * {@link Opcodes#UNINITIALIZED_THIS} (long and double are represented by a
79      * two elements, the second one being TOP). Reference types are represented
80      * by String objects (representing internal names, or type descriptors for
81      * array types), and uninitialized types by Label objects (this label
82      * designates the NEW instruction that created this uninitialized value).
83      * This field is <tt>null</tt> for unreacheable instructions.
84      */

85     public List JavaDoc stack;
86
87     /**
88      * The labels that designate the next instruction to be visited. May be
89      * <tt>null</tt>.
90      */

91     private List JavaDoc labels;
92
93     /**
94      * Information about uninitialized types in the current execution frame.
95      * This map associates internal names to Label objects. Each label
96      * designates a NEW instruction that created the currently uninitialized
97      * types, and the associated internal name represents the NEW operand, i.e.
98      * the final, initialized type value.
99      */

100     private Map JavaDoc uninitializedTypes;
101
102     /**
103      * The maximum stack size of this method.
104      */

105     private int maxStack;
106
107     /**
108      * The maximum number of local variables of this method.
109      */

110     private int maxLocals;
111
112     /**
113      * Creates a new {@link AnalyzerAdapter}.
114      *
115      * @param owner the owner's class name.
116      * @param access the method's access flags (see {@link Opcodes}).
117      * @param name the method's name.
118      * @param desc the method's descriptor (see {@link Type Type}).
119      * @param mv the method visitor to which this adapter delegates calls. May
120      * be <tt>null</tt>.
121      */

122     public AnalyzerAdapter(
123         final String JavaDoc owner,
124         final int access,
125         final String JavaDoc name,
126         final String JavaDoc desc,
127         final MethodVisitor mv)
128     {
129         super(mv);
130         locals = new ArrayList JavaDoc();
131         stack = new ArrayList JavaDoc();
132         uninitializedTypes = new HashMap JavaDoc();
133
134         if ((access & Opcodes.ACC_STATIC) == 0) {
135             if (name.equals("<init>")) {
136                 locals.add(Opcodes.UNINITIALIZED_THIS);
137             } else {
138                 locals.add(owner);
139             }
140         }
141         Type[] types = Type.getArgumentTypes(desc);
142         for (int i = 0; i < types.length; ++i) {
143             Type type = types[i];
144             switch (type.getSort()) {
145                 case Type.BOOLEAN:
146                 case Type.CHAR:
147                 case Type.BYTE:
148                 case Type.SHORT:
149                 case Type.INT:
150                     locals.add(Opcodes.INTEGER);
151                     break;
152                 case Type.FLOAT:
153                     locals.add(Opcodes.FLOAT);
154                     break;
155                 case Type.LONG:
156                     locals.add(Opcodes.LONG);
157                     locals.add(Opcodes.TOP);
158                     break;
159                 case Type.DOUBLE:
160                     locals.add(Opcodes.DOUBLE);
161                     locals.add(Opcodes.TOP);
162                     break;
163                 case Type.ARRAY:
164                     locals.add(types[i].getDescriptor());
165                     break;
166                 // case Type.OBJECT:
167
default:
168                     locals.add(types[i].getInternalName());
169             }
170         }
171     }
172
173     public void visitFrame(
174         final int type,
175         final int nLocal,
176         final Object JavaDoc[] local,
177         final int nStack,
178         final Object JavaDoc[] stack)
179     {
180         if (type != Opcodes.F_NEW) { // uncompressed frame
181
throw new IllegalStateException JavaDoc("ClassReader.accept() should be called with EXPAND_FRAMES flag");
182         }
183
184         if (mv != null) {
185             mv.visitFrame(type, nLocal, local, nStack, stack);
186         }
187
188         if (this.locals != null) {
189             this.locals.clear();
190             this.stack.clear();
191         } else {
192             this.locals = new ArrayList JavaDoc();
193             this.stack = new ArrayList JavaDoc();
194         }
195         visitFrameTypes(nLocal, local, this.locals);
196         visitFrameTypes(nStack, stack, this.stack);
197         maxStack = Math.max(maxStack, this.stack.size());
198     }
199
200     private void visitFrameTypes(
201         final int n,
202         final Object JavaDoc[] types,
203         final List JavaDoc result)
204     {
205         for (int i = 0; i < n; ++i) {
206             Object JavaDoc type = types[i];
207             result.add(type);
208             if (type == Opcodes.LONG || type == Opcodes.DOUBLE) {
209                 result.add(Opcodes.TOP);
210             }
211         }
212     }
213
214     public void visitInsn(final int opcode) {
215         if (mv != null) {
216             mv.visitInsn(opcode);
217         }
218         execute(opcode, 0, null);
219         if ((opcode >= Opcodes.IRETURN && opcode <= Opcodes.RETURN)
220                 || opcode == Opcodes.ATHROW)
221         {
222             this.locals = null;
223             this.stack = null;
224         }
225     }
226
227     public void visitIntInsn(final int opcode, final int operand) {
228         if (mv != null) {
229             mv.visitIntInsn(opcode, operand);
230         }
231         execute(opcode, operand, null);
232     }
233
234     public void visitVarInsn(final int opcode, final int var) {
235         if (mv != null) {
236             mv.visitVarInsn(opcode, var);
237         }
238         execute(opcode, var, null);
239     }
240
241     public void visitTypeInsn(final int opcode, final String JavaDoc desc) {
242         if (opcode == Opcodes.NEW) {
243             if (labels == null) {
244                 Label l = new Label();
245                 labels = new ArrayList JavaDoc(3);
246                 labels.add(l);
247                 if (mv != null) {
248                     mv.visitLabel(l);
249                 }
250             }
251             for (int i = 0; i < labels.size(); ++i) {
252                 uninitializedTypes.put(labels.get(i), desc);
253             }
254         }
255         if (mv != null) {
256             mv.visitTypeInsn(opcode, desc);
257         }
258         execute(opcode, 0, desc);
259     }
260
261     public void visitFieldInsn(
262         final int opcode,
263         final String JavaDoc owner,
264         final String JavaDoc name,
265         final String JavaDoc desc)
266     {
267         if (mv != null) {
268             mv.visitFieldInsn(opcode, owner, name, desc);
269         }
270         execute(opcode, 0, desc);
271     }
272
273     public void visitMethodInsn(
274         final int opcode,
275         final String JavaDoc owner,
276         final String JavaDoc name,
277         final String JavaDoc desc)
278     {
279         if (mv != null) {
280             mv.visitMethodInsn(opcode, owner, name, desc);
281         }
282         pop(desc);
283         if (opcode != Opcodes.INVOKESTATIC) {
284             Object JavaDoc t = pop();
285             if (opcode == Opcodes.INVOKESPECIAL && name.charAt(0) == '<') {
286                 Object JavaDoc u;
287                 if (t == Opcodes.UNINITIALIZED_THIS) {
288                     u = owner;
289                 } else {
290                     u = uninitializedTypes.get(t);
291                 }
292                 for (int i = 0; i < locals.size(); ++i) {
293                     if (locals.get(i) == t) {
294                         locals.set(i, u);
295                     }
296                 }
297                 for (int i = 0; i < stack.size(); ++i) {
298                     if (stack.get(i) == t) {
299                         stack.set(i, u);
300                     }
301                 }
302             }
303         }
304         pushDesc(desc);
305         labels = null;
306     }
307
308     public void visitJumpInsn(final int opcode, final Label label) {
309         if (mv != null) {
310             mv.visitJumpInsn(opcode, label);
311         }
312         execute(opcode, 0, null);
313         if (opcode == Opcodes.GOTO) {
314             this.locals = null;
315             this.stack = null;
316         }
317     }
318
319     public void visitLabel(final Label label) {
320         if (mv != null) {
321             mv.visitLabel(label);
322         }
323         if (labels == null) {
324             labels = new ArrayList JavaDoc(3);
325         }
326         labels.add(label);
327     }
328
329     public void visitLdcInsn(final Object JavaDoc cst) {
330         if (mv != null) {
331             mv.visitLdcInsn(cst);
332         }
333         if (cst instanceof Integer JavaDoc) {
334             push(Opcodes.INTEGER);
335         } else if (cst instanceof Long JavaDoc) {
336             push(Opcodes.LONG);
337             push(Opcodes.TOP);
338         } else if (cst instanceof Float JavaDoc) {
339             push(Opcodes.FLOAT);
340         } else if (cst instanceof Double JavaDoc) {
341             push(Opcodes.DOUBLE);
342             push(Opcodes.TOP);
343         } else if (cst instanceof String JavaDoc) {
344             push("java/lang/String");
345         } else if (cst instanceof Type) {
346             push("java/lang/Class");
347         } else {
348             throw new IllegalArgumentException JavaDoc();
349         }
350         labels = null;
351     }
352
353     public void visitIincInsn(final int var, final int increment) {
354         if (mv != null) {
355             mv.visitIincInsn(var, increment);
356         }
357         execute(Opcodes.IINC, var, null);
358     }
359
360     public void visitTableSwitchInsn(
361         final int min,
362         final int max,
363         final Label dflt,
364         final Label labels[])
365     {
366         if (mv != null) {
367             mv.visitTableSwitchInsn(min, max, dflt, labels);
368         }
369         execute(Opcodes.TABLESWITCH, 0, null);
370         this.locals = null;
371         this.stack = null;
372     }
373
374     public void visitLookupSwitchInsn(
375         final Label dflt,
376         final int keys[],
377         final Label labels[])
378     {
379         if (mv != null) {
380             mv.visitLookupSwitchInsn(dflt, keys, labels);
381         }
382         execute(Opcodes.LOOKUPSWITCH, 0, null);
383         this.locals = null;
384         this.stack = null;
385     }
386
387     public void visitMultiANewArrayInsn(final String JavaDoc desc, final int dims) {
388         if (mv != null) {
389             mv.visitMultiANewArrayInsn(desc, dims);
390         }
391         execute(Opcodes.MULTIANEWARRAY, dims, desc);
392     }
393
394     public void visitMaxs(final int maxStack, final int maxLocals) {
395         if (mv != null) {
396             this.maxStack = Math.max(this.maxStack, maxStack);
397             this.maxLocals = Math.max(this.maxLocals, maxLocals);
398             mv.visitMaxs(this.maxStack, this.maxLocals);
399         }
400     }
401
402     // ------------------------------------------------------------------------
403

404     private Object JavaDoc get(final int local) {
405         maxLocals = Math.max(maxLocals, local);
406         return local < locals.size() ? locals.get(local) : Opcodes.TOP;
407     }
408
409     private void set(final int local, final Object JavaDoc type) {
410         maxLocals = Math.max(maxLocals, local);
411         while (local >= locals.size()) {
412             locals.add(Opcodes.TOP);
413         }
414         locals.set(local, type);
415     }
416
417     private void push(final Object JavaDoc type) {
418         stack.add(type);
419         maxStack = Math.max(maxStack, stack.size());
420     }
421
422     private void pushDesc(final String JavaDoc desc) {
423         int index = desc.charAt(0) == '(' ? desc.indexOf(')') + 1 : 0;
424         switch (desc.charAt(index)) {
425             case 'V':
426                 return;
427             case 'Z':
428             case 'C':
429             case 'B':
430             case 'S':
431             case 'I':
432                 push(Opcodes.INTEGER);
433                 return;
434             case 'F':
435                 push(Opcodes.FLOAT);
436                 return;
437             case 'J':
438                 push(Opcodes.LONG);
439                 push(Opcodes.TOP);
440                 return;
441             case 'D':
442                 push(Opcodes.DOUBLE);
443                 push(Opcodes.TOP);
444                 return;
445             case '[':
446                 if (index == 0) {
447                     push(desc);
448                 } else {
449                     push(desc.substring(index, desc.length()));
450                 }
451                 break;
452             // case 'L':
453
default:
454                 if (index == 0) {
455                     push(desc.substring(1, desc.length() - 1));
456                 } else {
457                     push(desc.substring(index + 1, desc.length() - 1));
458                 }
459                 return;
460         }
461     }
462
463     private Object JavaDoc pop() {
464         return stack.remove(stack.size() - 1);
465     }
466
467     private void pop(final int n) {
468         int size = stack.size();
469         int end = size - n;
470         for (int i = size - 1; i >= end; --i) {
471             stack.remove(i);
472         }
473     }
474
475     private void pop(final String JavaDoc desc) {
476         char c = desc.charAt(0);
477         if (c == '(') {
478             int n = 0;
479             Type[] types = Type.getArgumentTypes(desc);
480             for (int i = 0; i < types.length; ++i) {
481                 n += types[i].getSize();
482             }
483             pop(n);
484         } else if (c == 'J' || c == 'D') {
485             pop(2);
486         } else {
487             pop(1);
488         }
489     }
490
491     private void execute(final int opcode, final int iarg, final String JavaDoc sarg) {
492         if (this.locals == null) {
493             return;
494         }
495         Object JavaDoc t1, t2, t3, t4;
496         switch (opcode) {
497             case Opcodes.NOP:
498             case Opcodes.INEG:
499             case Opcodes.LNEG:
500             case Opcodes.FNEG:
501             case Opcodes.DNEG:
502             case Opcodes.I2B:
503             case Opcodes.I2C:
504             case Opcodes.I2S:
505             case Opcodes.GOTO:
506             case Opcodes.RETURN:
507                 break;
508             case Opcodes.ACONST_NULL:
509                 push(Opcodes.NULL);
510                 break;
511             case Opcodes.ICONST_M1:
512             case Opcodes.ICONST_0:
513             case Opcodes.ICONST_1:
514             case Opcodes.ICONST_2:
515             case Opcodes.ICONST_3:
516             case Opcodes.ICONST_4:
517             case Opcodes.ICONST_5:
518             case Opcodes.BIPUSH:
519             case Opcodes.SIPUSH:
520                 push(Opcodes.INTEGER);
521                 break;
522             case Opcodes.LCONST_0:
523             case Opcodes.LCONST_1:
524                 push(Opcodes.LONG);
525                 push(Opcodes.TOP);
526                 break;
527             case Opcodes.FCONST_0:
528             case Opcodes.FCONST_1:
529             case Opcodes.FCONST_2:
530                 push(Opcodes.FLOAT);
531                 break;
532             case Opcodes.DCONST_0:
533             case Opcodes.DCONST_1:
534                 push(Opcodes.DOUBLE);
535                 push(Opcodes.TOP);
536                 break;
537             case Opcodes.ILOAD:
538             case Opcodes.FLOAD:
539             case Opcodes.ALOAD:
540                 push(get(iarg));
541                 break;
542             case Opcodes.LLOAD:
543             case Opcodes.DLOAD:
544                 push(get(iarg));
545                 push(Opcodes.TOP);
546                 break;
547             case Opcodes.IALOAD:
548             case Opcodes.BALOAD:
549             case Opcodes.CALOAD:
550             case Opcodes.SALOAD:
551                 pop(2);
552                 push(Opcodes.INTEGER);
553                 break;
554             case Opcodes.LALOAD:
555             case Opcodes.D2L:
556                 pop(2);
557                 push(Opcodes.LONG);
558                 push(Opcodes.TOP);
559                 break;
560             case Opcodes.FALOAD:
561                 pop(2);
562                 push(Opcodes.FLOAT);
563                 break;
564             case Opcodes.DALOAD:
565             case Opcodes.L2D:
566                 pop(2);
567                 push(Opcodes.DOUBLE);
568                 push(Opcodes.TOP);
569                 break;
570             case Opcodes.AALOAD:
571                 pop(1);
572                 t1 = pop();
573                 pushDesc(((String JavaDoc) t1).substring(1));
574                 break;
575             case Opcodes.ISTORE:
576             case Opcodes.FSTORE:
577             case Opcodes.ASTORE:
578                 t1 = pop();
579                 set(iarg, t1);
580                 if (iarg > 0) {
581                     t2 = get(iarg - 1);
582                     if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) {
583                         set(iarg - 1, Opcodes.TOP);
584                     }
585                 }
586                 break;
587             case Opcodes.LSTORE:
588             case Opcodes.DSTORE:
589                 pop(1);
590                 t1 = pop();
591                 set(iarg, t1);
592                 set(iarg + 1, Opcodes.TOP);
593                 if (iarg > 0) {
594                     t2 = get(iarg - 1);
595                     if (t2 == Opcodes.LONG || t2 == Opcodes.DOUBLE) {
596                         set(iarg - 1, Opcodes.TOP);
597                     }
598                 }
599                 break;
600             case Opcodes.IASTORE:
601             case Opcodes.BASTORE:
602             case Opcodes.CASTORE:
603             case Opcodes.SASTORE:
604             case Opcodes.FASTORE:
605             case Opcodes.AASTORE:
606                 pop(3);
607                 break;
608             case Opcodes.LASTORE:
609             case Opcodes.DASTORE:
610                 pop(4);
611                 break;
612             case Opcodes.POP:
613             case Opcodes.IFEQ:
614             case Opcodes.IFNE:
615             case Opcodes.IFLT:
616             case Opcodes.IFGE:
617             case Opcodes.IFGT:
618             case Opcodes.IFLE:
619             case Opcodes.IRETURN:
620             case Opcodes.FRETURN:
621             case Opcodes.ARETURN:
622             case Opcodes.TABLESWITCH:
623             case Opcodes.LOOKUPSWITCH:
624             case Opcodes.ATHROW:
625             case Opcodes.MONITORENTER:
626             case Opcodes.MONITOREXIT:
627             case Opcodes.IFNULL:
628             case Opcodes.IFNONNULL:
629                 pop(1);
630                 break;
631             case Opcodes.POP2:
632             case Opcodes.IF_ICMPEQ:
633             case Opcodes.IF_ICMPNE:
634             case Opcodes.IF_ICMPLT:
635             case Opcodes.IF_ICMPGE:
636             case Opcodes.IF_ICMPGT:
637             case Opcodes.IF_ICMPLE:
638             case Opcodes.IF_ACMPEQ:
639             case Opcodes.IF_ACMPNE:
640             case Opcodes.LRETURN:
641             case Opcodes.DRETURN:
642                 pop(2);
643                 break;
644             case Opcodes.DUP:
645                 t1 = pop();
646                 push(t1);
647                 push(t1);
648                 break;
649             case Opcodes.DUP_X1:
650                 t1 = pop();
651                 t2 = pop();
652                 push(t1);
653                 push(t2);
654                 push(t1);
655                 break;
656             case Opcodes.DUP_X2:
657                 t1 = pop();
658                 t2 = pop();
659                 t3 = pop();
660                 push(t1);
661                 push(t3);
662                 push(t2);
663                 push(t1);
664                 break;
665             case Opcodes.DUP2:
666                 t1 = pop();
667                 t2 = pop();
668                 push(t2);
669                 push(t1);
670                 push(t2);
671                 push(t1);
672                 break;
673             case Opcodes.DUP2_X1:
674                 t1 = pop();
675                 t2 = pop();
676                 t3 = pop();
677                 push(t2);
678                 push(t1);
679                 push(t3);
680                 push(t2);
681                 push(t1);
682                 break;
683             case Opcodes.DUP2_X2:
684                 t1 = pop();
685                 t2 = pop();
686                 t3 = pop();
687                 t4 = pop();
688                 push(t2);
689                 push(t1);
690                 push(t4);
691                 push(t3);
692                 push(t2);
693                 push(t1);
694                 break;
695             case Opcodes.SWAP:
696                 t1 = pop();
697                 t2 = pop();
698                 push(t1);
699                 push(t2);
700                 break;
701             case Opcodes.IADD:
702             case Opcodes.ISUB:
703             case Opcodes.IMUL:
704             case Opcodes.IDIV:
705             case Opcodes.IREM:
706             case Opcodes.IAND:
707             case Opcodes.IOR:
708             case Opcodes.IXOR:
709             case Opcodes.ISHL:
710             case Opcodes.ISHR:
711             case Opcodes.IUSHR:
712             case Opcodes.L2I:
713             case Opcodes.D2I:
714             case Opcodes.FCMPL:
715             case Opcodes.FCMPG:
716                 pop(2);
717                 push(Opcodes.INTEGER);
718                 break;
719             case Opcodes.LADD:
720             case Opcodes.LSUB:
721             case Opcodes.LMUL:
722             case Opcodes.LDIV:
723             case Opcodes.LREM:
724             case Opcodes.LAND:
725             case Opcodes.LOR:
726             case Opcodes.LXOR:
727                 pop(4);
728                 push(Opcodes.LONG);
729                 push(Opcodes.TOP);
730                 break;
731             case Opcodes.FADD:
732             case Opcodes.FSUB:
733             case Opcodes.FMUL:
734             case Opcodes.FDIV:
735             case Opcodes.FREM:
736             case Opcodes.L2F:
737             case Opcodes.D2F:
738                 pop(2);
739                 push(Opcodes.FLOAT);
740                 break;
741             case Opcodes.DADD:
742             case Opcodes.DSUB:
743             case Opcodes.DMUL:
744             case Opcodes.DDIV:
745             case Opcodes.DREM:
746                 pop(4);
747                 push(Opcodes.DOUBLE);
748                 push(Opcodes.TOP);
749                 break;
750             case Opcodes.LSHL:
751             case Opcodes.LSHR:
752             case Opcodes.LUSHR:
753                 pop(3);
754                 push(Opcodes.LONG);
755                 push(Opcodes.TOP);
756                 break;
757             case Opcodes.IINC:
758                 set(iarg, Opcodes.INTEGER);
759                 break;
760             case Opcodes.I2L:
761             case Opcodes.F2L:
762                 pop(1);
763                 push(Opcodes.LONG);
764                 push(Opcodes.TOP);
765                 break;
766             case Opcodes.I2F:
767                 pop(1);
768                 push(Opcodes.FLOAT);
769                 break;
770             case Opcodes.I2D:
771             case Opcodes.F2D:
772                 pop(1);
773                 push(Opcodes.DOUBLE);
774                 push(Opcodes.TOP);
775                 break;
776             case Opcodes.F2I:
777             case Opcodes.ARRAYLENGTH:
778             case Opcodes.INSTANCEOF:
779                 pop(1);
780                 push(Opcodes.INTEGER);
781                 break;
782             case Opcodes.LCMP:
783             case Opcodes.DCMPL:
784             case Opcodes.DCMPG:
785                 pop(4);
786                 push(Opcodes.INTEGER);
787                 break;
788             case Opcodes.JSR:
789             case Opcodes.RET:
790                 throw new RuntimeException JavaDoc("JSR/RET are not supported");
791             case Opcodes.GETSTATIC:
792                 pushDesc(sarg);
793                 break;
794             case Opcodes.PUTSTATIC:
795                 pop(sarg);
796                 break;
797             case Opcodes.GETFIELD:
798                 pop(1);
799                 pushDesc(sarg);
800                 break;
801             case Opcodes.PUTFIELD:
802                 pop(sarg);
803                 pop();
804                 break;
805             case Opcodes.NEW:
806                 push(labels.get(0));
807                 break;
808             case Opcodes.NEWARRAY:
809                 pop();
810                 switch (iarg) {
811                     case Opcodes.T_BOOLEAN:
812                         pushDesc("[Z");
813                         break;
814                     case Opcodes.T_CHAR:
815                         pushDesc("[C");
816                         break;
817                     case Opcodes.T_BYTE:
818                         pushDesc("[B");
819                         break;
820                     case Opcodes.T_SHORT:
821                         pushDesc("[S");
822                         break;
823                     case Opcodes.T_INT:
824                         pushDesc("[I");
825                         break;
826                     case Opcodes.T_FLOAT:
827                         pushDesc("[F");
828                         break;
829                     case Opcodes.T_DOUBLE:
830                         pushDesc("[D");
831                         break;
832                     // case Opcodes.T_LONG:
833
default:
834                         pushDesc("[J");
835                         break;
836                 }
837                 break;
838             case Opcodes.ANEWARRAY:
839                 pop();
840                 if (sarg.charAt(0) == '[') {
841                     pushDesc("[" + sarg);
842                 } else {
843                     pushDesc("[L" + sarg + ";");
844                 }
845                 break;
846             case Opcodes.CHECKCAST:
847                 pop();
848                 if (sarg.charAt(0) == '[') {
849                     pushDesc(sarg);
850                 } else {
851                     push(sarg);
852                 }
853                 break;
854             // case Opcodes.MULTIANEWARRAY:
855
default:
856                 pop(iarg);
857                 pushDesc(sarg);
858                 break;
859         }
860         labels = null;
861     }
862 }
863
Popular Tags