KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jbet > Instruction


1 /*
2  * JBET - Java Binary Enhancement Tool
3  * Copyright (c) 2003 Networks Associates Technology, Inc.
4  *
5  * This software was developed under DARPA/SPAWAR contract
6  * N66001-00-C-8602 "SPMA" as part of the
7  * DARPA OASIS research program.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
19  * 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 AUTHOR OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28  * SUCH DAMAGE.
29  */

30
31 package jbet;
32 import java.io.*;
33 import java.util.*;
34
35 /**
36  * An instance of this class represents a single JVM instruction,
37  * along with any in-line data. This class knows how to build itself
38  * out of the JVM bytecode format, and how to write itself out in that
39  * format. The data members of this class hold the "content" of the
40  * instruction, for code analysis and editing purposes.
41  *
42  * Instruction has quite a few fields and usualy only a few are in use
43  * at any one time. We use accessor methods so we can switch to a
44  * more economical storage later if we want to.
45  *
46  * Branch targets are considered to be owned by their instructions.
47  * They may not be shared.
48  *
49  * @author Lee Badger
50  * @author Larry D'anna
51  * @version 0.1
52  * @since JDK 1.1.8 */

53
54 public final class Instruction implements Cloneable JavaDoc{
55
56     private int _opCode;
57     private int _realOpCode; /* the opcode we read it in as.
58                 * Used to make perfect copies
59                 * just a hint, not always present */

60
61
62     /* these two are used during reads and writes */
63     private int _pc;
64     private int _index;
65     private int _cpItemIndex;
66
67
68     /* for instructions using the Local Variable Table */
69     private int _lvtIndex;
70
71     /* universal place to put immediate data */
72     private long _immediate;
73     private double _immediate_f;
74     private String JavaDoc _immediate_s;
75
76     /* switch instruction */
77     private BranchTarget _switchArray[];
78
79     /* tableswitch uses immediate for lowbound, they both use
80        switchArray.length for the table size */

81
82     /* branch targets and refs */
83     private Object JavaDoc _ref;
84
85     /* method or field name and type */
86     private String JavaDoc _elemname;
87     private Object JavaDoc _lvname;
88     private Object JavaDoc _type;
89
90     
91     public Instruction next = null, prev = null;
92
93     Object JavaDoc _procState = null; // for DataFlow
94
Object JavaDoc _lvrec = null;
95
96     /**
97      * make this a verbatim copy of i
98      * @param i
99      */

100     public void copy (Instruction i) {
101     _opCode = i._opCode;
102     _realOpCode = i._realOpCode;
103     _pc = i._pc;
104     _cpItemIndex = i._cpItemIndex;
105     _lvtIndex = i._lvtIndex;
106     _immediate = i._immediate;
107     _immediate_f = i._immediate_f;
108     _immediate_s = i._immediate_s;
109     _switchArray = i._switchArray;
110     _ref = i._ref;
111     _type = i._type;
112     _elemname = i._elemname;
113     _procState = i._procState;
114     _lvname = i._lvname;
115     _index = i._index;
116     }
117
118     /**
119      * call this first
120      */

121     void initialize() {
122     _realOpCode = -1;
123     _cpItemIndex = -1;
124     _ref = null;
125     _switchArray = null;
126     _type = null;
127     _elemname = null;
128     }
129         
130
131     /** Field getter and setter functions.
132      */

133     public int opCode() { return _opCode; }
134     public int setOpCode(int o) { return _opCode = o ; }
135
136     public int realOpCode() { return _realOpCode; }
137     public int setRealOpCode(int o) { return _realOpCode = o;}
138
139     int cpItemIndex() { return _cpItemIndex; }
140     int setCpItemIndex(int i) { return _cpItemIndex = i; }
141
142     int blockNumber() { return _cpItemIndex; }
143     int setBlockNumber(int b) { return _cpItemIndex = b; }
144
145     public int lvtIndex() { return _lvtIndex; };
146     public int setLvtIndex(int i) { return _lvtIndex = i; }
147     
148     public int immediate() { return (int) _immediate; }
149     public int setImmediate(int i) { return (int) (_immediate = i); }
150
151     public long immediate_l() { return _immediate; }
152     public long setImmediate_l(long l) { return _immediate = l ; }
153     
154     public double immediate_f() { return _immediate_f; }
155     public double setImmediate_f(double d) { return _immediate_f = d; }
156
157     public String JavaDoc immediate_s() { return _immediate_s; }
158     public String JavaDoc setImmediate_s(String JavaDoc d) { return _immediate_s = d; }
159
160     public String JavaDoc lvname() { return (String JavaDoc) _lvrec; }
161     public String JavaDoc setLvname(String JavaDoc d) { return (String JavaDoc) (_lvrec = d); }
162
163     public BranchTarget branchTarget() { return (BranchTarget) _ref; }
164     public BranchTarget setBranchTarget(BranchTarget t) {
165     return (BranchTarget) (_ref = t);
166     }
167
168     public BranchTarget [] switchArray() { return _switchArray; }
169     public BranchTarget [] setSwitchArray(BranchTarget [] a) {
170     return _switchArray = a;
171     }
172     
173     public String JavaDoc classRef() { return (String JavaDoc) _ref;}
174     public String JavaDoc setClassRef(String JavaDoc s) { return (String JavaDoc) (_ref = s); }
175
176     public String JavaDoc elemName() { return _elemname; };
177     public String JavaDoc setElemName(String JavaDoc s) { return (_elemname = s);}
178     
179     public Type type() { return (Type) _type; }
180     public Type setType(Type t) { return (Type) ( _type = t); }
181
182     Object JavaDoc rawType() { return _type; }
183
184     public Descriptor descriptor() { return (Descriptor) _type; }
185     public Descriptor setDescriptor(Descriptor t) {
186     return (Descriptor) ( _type = t);
187     }
188
189     public int pc() { return _pc; };
190     public int setPc(int i) { return _pc = i; }
191
192     public DataFlow.ProcState procState() { return (DataFlow.ProcState) _procState; }
193     DataFlow.ProcState setProcState(DataFlow.ProcState s) {
194     return (DataFlow.ProcState) (_procState = s);
195     }
196
197     void model () throws ClassFileException, DataFlowException
198     {
199     procState().model (this);
200     }
201
202     /* we don't use index and pc at the same times */
203     int index() { return _index; };
204     int setIndex(int i) { return _index = i; };
205
206     public void setBranchTarget(Instruction instr) {
207     if ( branchTarget() == null )
208         setBranchTarget( new BranchTarget() );
209     branchTarget().instr = instr;
210     }
211
212     public void setBranchTarget (Block b) {
213     if (branchTarget() == null)
214         setBranchTarget (new BranchTarget ());
215     branchTarget().block = b;
216     }
217
218     public Instruction dup() {
219     try {
220         Instruction instr = (Instruction) clone();
221         if (usesBranch())
222         instr.setBranchTarget( branchTarget().dup() );
223         if (isSwitch()) {
224         BranchTarget [] sa = switchArray();
225         BranchTarget [] sa2 = new BranchTarget [ sa.length ];
226         for (int i = 0; i < sa.length; i++)
227             sa2[i] = sa[i].dup();
228         instr.setSwitchArray( sa2 );
229         }
230         if (procState () != null)
231         instr.setProcState (procState().dup());
232         return instr;
233     } catch (CloneNotSupportedException JavaDoc e) {
234         return null;
235     }
236     }
237
238     /* "constructors" */
239
240     /** Set this to a NOP
241      * @return a reference to this
242      */

243     public Instruction setNop() {
244     initialize();
245     setOpCode(OP_NOP);
246     return this;
247     }
248
249     /** Set this to an comment string
250      * @param s comment string
251      * @return a reference to this
252      */

253     public Instruction setComment (String JavaDoc s) {
254     initialize();
255     setOpCode (AOP_COMMENT);
256     setImmediate_s (s);
257     return this;
258     }
259
260     /** Set this to an IFNULL
261      * @return a reference to this
262      */

263     public Instruction setIfNull() {
264     initialize();
265     setOpCode(OP_IFNULL);
266     setBranchTarget( new BranchTarget() );
267     return this;
268     }
269
270     public Instruction setIfNull(Instruction ins) {
271     initialize();
272     setOpCode(OP_IFNULL);
273     setBranchTarget( new BranchTarget(ins) );
274     return this;
275     }
276
277     /** Set this to an IFNONNULL
278      * @return a reference to this
279      */

280     public Instruction setIfNoNull() {
281     initialize();
282     setOpCode(OP_IFNONNULL);
283     setBranchTarget( new BranchTarget() );
284     return this;
285     }
286
287     public Instruction setIfNoNull(Instruction ins) {
288     initialize();
289     setOpCode(OP_IFNONNULL);
290     setBranchTarget( new BranchTarget(ins) );
291     return this;
292     }
293
294     /** Set this to a NEW
295      * @param s class reference
296      * @return a reference to this
297      */

298     public Instruction setNew(String JavaDoc s) {
299     initialize();
300     setOpCode(OP_NEW);
301     setClassRef (s);
302     return this;
303     }
304
305     /** Set this to a NEWARRAY
306      * @param atype one of the NAT_* values
307      * @return a reference to this
308      */

309     public Instruction setNewArray(int atype) {
310     initialize();
311     setOpCode(OP_NEWARRAY);
312     setImmediate (atype);
313     return this;
314     }
315
316     /** Set this to an ANEWARRAY
317      * @param s class reference
318      * @return a reference to this
319      */

320     public Instruction setANewArray (String JavaDoc s) {
321     initialize();
322     setOpCode(OP_ANEWARRAY);
323     setClassRef (s);
324     return this;
325     }
326
327     /** Set this to an MULTIANEWARRAY
328      * @param s class reference
329      * @return a reference to this
330      */

331     public Instruction setMultiaNewArray (String JavaDoc s, int n) {
332     initialize();
333     setOpCode(OP_MULTIANEWARRAY);
334     setClassRef (s);
335     setImmediate (n);
336     return this;
337     }
338
339     /** Set this to an INSTANCEOF
340      * @param s class reference
341      * @return a reference to this
342      */

343     public Instruction setInstanceof(String JavaDoc s) {
344     initialize();
345     setOpCode(OP_INSTANCEOF);
346     setClassRef (s);
347     return this;
348     }
349
350     /** Set this to a CHECKCAST
351      * @param t a type to check
352      * @return a reference to this
353      */

354     public Instruction setInstanceof(Type t) {
355     initialize();
356     setOpCode(OP_INSTANCEOF);
357     setClassRef (t.toClassRef());
358     return this;
359     }
360
361     /** Set this to a CHECKCAST
362      * @param s class reference
363      * @return a reference to this
364      */

365     public Instruction setCheckcast(String JavaDoc s) {
366     initialize();
367     setOpCode(OP_CHECKCAST);
368     setClassRef (s);
369     return this;
370     }
371
372     /** Set this to a CHECKCAST
373      * @param t a type to check
374      * @return a reference to this
375      */

376     public Instruction setCheckcast(Type t) {
377     initialize();
378     setOpCode(OP_CHECKCAST);
379     setClassRef (t.toClassRef());
380     return this;
381     }
382
383     
384     /** Set this to an INVOKESTATIC
385      * @param cname class name
386      * @param ename element name
387      * @param d type descriptor
388      * @return a reference to this
389      */

390     public Instruction setInvokeStatic(String JavaDoc cname, String JavaDoc ename, Descriptor d) {
391     initialize();
392     setOpCode(OP_INVOKESTATIC);
393     setClassRef(cname);
394     setElemName(ename);
395     setDescriptor(d);
396     return this;
397     }
398
399     /** Set this to an INVOKEVIRTUAL
400      * @param cname class name
401      * @param ename element name
402      * @param d type descriptor
403      * @return a reference to this
404      */

405     public Instruction setInvokeVirtual(String JavaDoc cname, String JavaDoc ename, Descriptor d) {
406     initialize();
407     setOpCode(OP_INVOKEVIRTUAL);
408     setClassRef(cname);
409     setElemName(ename);
410     setDescriptor(d);
411     return this;
412     }
413
414     /** Set this to an INVOKESPECIAL
415      * @param cname class name
416      * @param ename element name
417      * @param d type descriptor
418      * @return a reference to this
419      */

420     public Instruction setInvokeSpecial(String JavaDoc cname, String JavaDoc ename, Descriptor d) {
421     initialize();
422     setOpCode(OP_INVOKESPECIAL);
423     setClassRef(cname);
424     setElemName(ename);
425     setDescriptor(d);
426     return this;
427     }
428
429     /** Set this to an invoke
430      * @param cname class name
431      * @param ename element name
432      * @param d type descriptor
433      * @return a reference to this
434      */

435     public Instruction setInvoke(String JavaDoc cname, String JavaDoc ename, Descriptor d, int op) {
436     initialize();
437     setOpCode(op);
438     setClassRef(cname);
439     setElemName(ename);
440     setDescriptor(d);
441     return this;
442     }
443     
444     /** Set this to an INVOKESTATIC or INVOKEVIRTUAL
445      * @param cname class name
446      * @param ename element name
447      * @param d type descriptor
448      * @param isStatic TRUE if static
449      * @return a reference to this
450      */

451     public Instruction setInvoke(String JavaDoc cname,
452               String JavaDoc ename,
453               Descriptor d,
454               boolean isStatic) {
455     initialize();
456     setOpCode(isStatic ? OP_INVOKESTATIC : OP_INVOKEVIRTUAL);
457     setClassRef(cname);
458     setElemName(ename);
459     setDescriptor(d);
460     return this;
461     }
462
463
464     /** Set this to a GETFIELD
465      * @param cname class name
466      * @param field field name
467      * @param t type
468      * @return a reference to this
469      */

470     public Instruction setGetfield(String JavaDoc cname, String JavaDoc field, Type t) {
471     initialize();
472     setOpCode(OP_GETFIELD);
473     setClassRef(cname);
474     setElemName(field);
475     setType(t);
476     return this;
477    }
478
479     public boolean isGet() {
480     return opCode() == OP_GETFIELD || opCode() == OP_GETSTATIC;
481     }
482     public boolean isPut() {
483     return opCode() == OP_PUTFIELD || opCode() == OP_PUTSTATIC;
484     }
485
486     /** Set this to a GETSTATIC
487      * @param cname class name
488      * @param field field name
489      * @param t type
490      * @return a reference to this
491      */

492     public Instruction setGetstatic(String JavaDoc cname, String JavaDoc field, Type t) {
493     initialize();
494     setOpCode(OP_GETSTATIC);
495     setClassRef(cname);
496     setElemName(field);
497     setType(t);
498     return this;
499    }
500
501     /** Set this to a PUTFIELD
502      * @param cname class name
503      * @param field field name
504      * @param t type
505      * @return a reference to this
506      */

507     public Instruction setPutfield(String JavaDoc cname, String JavaDoc field, Type t) {
508     initialize();
509     setOpCode(OP_PUTFIELD);
510     setClassRef(cname);
511     setElemName(field);
512     setType(t);
513     return this;
514    }
515
516     /** Set this to a PUTSTATIC
517      * @param cname class name
518      * @param field field name
519      * @param t type
520      * @return a reference to this
521      */

522     public Instruction setPutstatic(String JavaDoc cname, String JavaDoc field, Type t) {
523     initialize();
524     setOpCode(OP_PUTSTATIC);
525     setClassRef(cname);
526     setElemName(field);
527     setType(t);
528     return this;
529    }
530
531     /** Set this to a DUP
532      * @return a reference to this
533      */

534     public Instruction setDup() {
535     initialize();
536     setOpCode(OP_DUP);
537     return this;
538     }
539
540     /** Set this to a DUP2
541      * @return a reference to this
542      */

543     public Instruction setDup2() {
544     initialize();
545     setOpCode(OP_DUP2);
546     return this;
547     }
548
549     /** Set this to a DUP or DUP2 depending on type
550      * @return a reference to this
551      */

552     public Instruction setDup (Type t) {
553     initialize();
554     setOpCode(t.category() == 1 ? OP_DUP : OP_DUP2);
555     return this;
556     }
557
558     /* Set this to the appropriate dup instruction for copying a T at the
559        top of stack underneath an OVER which is second from the top. */

560
561     public Instruction setDup_x (Type t, Type over) {
562     initialize();
563     if (t.category() == 1) {
564         if (over.category() == 1)
565         setOpCode (OP_DUP_X1);
566         else
567         setOpCode (OP_DUP_X2);
568     } else {
569         if (over.category() == 1)
570         setOpCode (OP_DUP2_X1);
571         else
572         setOpCode (OP_DUP2_X2);
573     }
574     return this;
575     }
576
577     /** Set this to an ACONST_NULL
578      * @return a reference to this
579      */

580     public Instruction setAconst_Null() {
581     initialize();
582     setOpCode(OP_ACONST_NULL);
583     return this;
584     }
585
586     /** Set this to an ATHROW
587      * @return a reference to this
588      */

589     public Instruction setAthrow() {
590     initialize();
591     setOpCode(OP_ATHROW);
592     return this;
593     }
594
595     /** Set this to an ARETURN
596      * @return a reference to this
597      */

598     public Instruction setAreturn() {
599     initialize();
600     setOpCode(OP_ARETURN);
601     return this;
602     }
603
604     /** Set this to an IRETURN
605      * @return a reference to this
606      */

607     public Instruction setIreturn() {
608     initialize();
609     setOpCode(OP_IRETURN);
610     return this;
611     }
612
613     /** Set this to a DRETURN
614      * @return a reference to this
615      */

616     public Instruction setDreturn() {
617     initialize();
618     setOpCode(OP_DRETURN);
619     return this;
620     }
621
622     /** Set this to an FRETURN
623      * @return a reference to this
624      */

625     public Instruction setFreturn() {
626     initialize();
627     setOpCode(OP_FRETURN);
628     return this;
629     }
630
631     /** Set this to an LRETURN
632      * @return a reference to this
633      */

634     public Instruction setLreturn() {
635     initialize();
636     setOpCode(OP_LRETURN);
637     return this;
638     }
639
640     /** Set this to a RETURN
641      * @return a reference to this
642      */

643     public Instruction setReturn() {
644     initialize();
645     setOpCode(OP_RETURN);
646     return this;
647     }
648
649     /** Set this to a POP
650      * @return a reference to this
651      */

652     public Instruction setPop() {
653     initialize();
654     setOpCode(OP_POP);
655     return this;
656     }
657
658     /** Set this to a POP2
659      * @return a reference to this
660      */

661     public Instruction setPop2() {
662     initialize();
663     setOpCode(OP_POP2);
664     return this;
665     }
666
667     /** Set this to a POP or POP2 depending on type
668      * @return a reference to this
669      */

670     public Instruction setPop (Type t) {
671     initialize();
672     if (t.category() == 0) setNop();
673     else setOpCode(t.category() == 1 ? OP_POP : OP_POP2);
674     return this;
675     }
676
677     /** Set this to a DUP_X1
678      * @return a reference to this
679      */

680     public Instruction setDup_x1() {
681     initialize();
682     setOpCode(OP_DUP_X1);
683     return this;
684     }
685
686     /** Set this to a DUP_X2
687      * @return a reference to this
688      */

689     public Instruction setDup_x2() {
690     initialize();
691     setOpCode(OP_DUP_X2);
692     return this;
693     }
694
695     /** Set this to a DUP2_X1
696      * @return a reference to this
697      */

698     public Instruction setDup2_x1() {
699     initialize();
700     setOpCode(OP_DUP2_X1);
701     return this;
702     }
703
704     /** Set this to a DUP2_X2
705      * @return a reference to this
706      */

707     public Instruction setDup2_x2() {
708     initialize();
709     setOpCode(OP_DUP2_X2);
710     return this;
711     }
712
713     /** Set this to an IPUSH
714      * @param i int value to push
715      * @return a reference to this
716      */

717     public Instruction setIpush (int i) {
718     initialize();
719     setOpCode(AOP_IPUSH);
720     setImmediate(i);
721     return this;
722     }
723
724     /** Set this to a DPUSH
725      * @param i double to push
726      * @return a reference to this
727      */

728     public Instruction setDpush (double i) {
729     initialize();
730     setOpCode(AOP_DPUSH);
731     setImmediate_f(i);
732     return this;
733     }
734
735     /** Set this to an FPUSH
736      * @param i double value to push
737      * @return a reference to this
738      */

739     public Instruction setFpush (double i) {
740     initialize();
741     setOpCode(AOP_FPUSH);
742     setImmediate_f(i);
743     return this;
744     }
745
746     /** Set this to an LPUSH
747      * @param i long value to push
748      * @return a reference to this
749      */

750     public Instruction setLpush (long i) {
751     initialize();
752     setOpCode(AOP_LPUSH);
753     setImmediate_l(i);
754     return this;
755     }
756
757     /** Set this to an SPUSH
758      * @param s string value to push
759      * @return a reference to this
760      */

761     public Instruction setSpush (String JavaDoc s) {
762     initialize();
763     setOpCode(AOP_SPUSH);
764     setImmediate_s(s);
765     return this;
766     }
767     
768     /** Set this to the correct LOAD opcode depending on type
769      * @param t type of value
770      * @param lvt index
771      * @return a reference to this
772      */

773     public Instruction setLoad (Type t, int lvt) {
774     initialize();
775     setLvtIndex (lvt);
776
777     if (t.arraydepth > 0) {
778         setOpCode (OP_ALOAD);
779         return this;
780     }
781
782     switch (t.base) {
783     case 'L':
784     case 'l':
785     case 'N':
786     case 'R':
787         setOpCode (OP_ALOAD);
788         break;
789         case 'S':
790     case 'I':
791     case 'Z':
792     case 'C':
793     case 'B':
794         setOpCode (OP_ILOAD);
795         break;
796     case 'J':
797         setOpCode (OP_LLOAD);
798         break;
799     case 'D':
800         setOpCode (OP_DLOAD);
801         break;
802     case 'F':
803         setOpCode (OP_FLOAD);
804         break;
805     default:
806         throw new IllegalStateException JavaDoc ("invalid type for setload");
807     }
808     return this;
809     }
810
811     /** Set this to a NEWARRAY
812      * @param array type of array to create. array can be the array or value type
813      * @return a reference to this
814      */

815     public Instruction setNewArray (Type array) {
816     initialize();
817
818     switch (array.base) {
819     case 'L':
820         setOpCode (OP_ANEWARRAY);
821         setClassRef (array.cname);
822         break;
823
824         case 'S':
825         setOpCode (OP_NEWARRAY);
826             setImmediate (NAT_SHORT);
827             break;
828
829     case 'I':
830         setOpCode(OP_NEWARRAY);
831         setImmediate (NAT_INT);
832         break;
833
834     case 'D':
835         setOpCode(OP_NEWARRAY);
836         setImmediate (NAT_DOUBLE);
837         break;
838
839     case 'F':
840         setOpCode(OP_NEWARRAY);
841         setImmediate (NAT_FLOAT);
842         break;
843
844     case 'J':
845         setOpCode(OP_NEWARRAY);
846         setImmediate (NAT_LONG);
847         break;
848
849     case 'Z':
850         setOpCode(OP_NEWARRAY);
851         setImmediate (NAT_BOOLEAN);
852         break;
853
854     case 'B':
855         setOpCode(OP_NEWARRAY);
856         setImmediate (NAT_BYTE);
857         break;
858
859     case 'C':
860         setOpCode(OP_NEWARRAY);
861         setImmediate (NAT_CHAR);
862         break;
863
864     default:
865         throw new IllegalStateException JavaDoc (array.base + ": invalid type for setnewarray");
866     }
867
868     return this;
869     }
870
871     /** Set this to the correct ALOAD opcode depending on type
872      * @param t type of value (not array)
873      * @return a reference to this
874      */

875     public Instruction setArrayLoad (Type t) {
876     initialize();
877
878     if (t.arraydepth > 1) {
879         setOpCode (OP_AALOAD);
880         return this;
881     }
882
883     switch (t.base) {
884     case 'L':
885         setOpCode (OP_AALOAD);
886         break;
887     case 'I':
888         setOpCode (OP_IALOAD);
889         break;
890     case 'J':
891         setOpCode (OP_LALOAD);
892         break;
893     case 'D':
894         setOpCode (OP_DALOAD);
895         break;
896     case 'F':
897         setOpCode (OP_FALOAD);
898         break;
899     case 'C':
900         setOpCode (OP_CALOAD);
901         break;
902         case 'S':
903             setOpCode (OP_SALOAD);
904             break;
905     case 'Z':
906     case 'B':
907         setOpCode (OP_BALOAD);
908         break;
909     default:
910         throw new IllegalStateException JavaDoc ("invalid type for setarrayload");
911     }
912     return this;
913     }
914
915     /** Set this to the correct ASTORE opcode depending on type
916      * @param t type of value or array
917      * @return a reference to this
918      */

919     public Instruction setArrayStore (Type t) {
920     initialize();
921
922     if (t.arraydepth > 1) {
923         setOpCode (OP_AASTORE);
924         return this;
925     }
926
927     switch (t.base) {
928     case 'L':
929         setOpCode (OP_AASTORE);
930         break;
931     case 'I':
932         setOpCode (OP_IASTORE);
933         break;
934     case 'J':
935         setOpCode (OP_LASTORE);
936         break;
937     case 'D':
938         setOpCode (OP_DASTORE);
939         break;
940     case 'F':
941         setOpCode (OP_FASTORE);
942         break;
943     case 'C':
944         setOpCode (OP_CASTORE);
945         break;
946         case 'S':
947             setOpCode (OP_SASTORE);
948             break;
949     case 'B':
950     case 'Z':
951         setOpCode (OP_BASTORE);
952         break;
953     default:
954         throw new IllegalStateException JavaDoc ("invalid type for setarraystore");
955     }
956     return this;
957     }
958     
959     /** Set this to the correct RETURN opcode depending on type
960      * @param t type of return
961      * @return a reference to this
962      */

963     public Instruction setReturn (Type t) {
964     initialize();
965
966     if (t == null) {
967         setOpCode (OP_RETURN);
968         return this;
969     }
970
971     if (t.arraydepth != 0) {
972         setOpCode (OP_ARETURN);
973         return this;
974     }
975
976     switch (t.base) {
977     case 'L':
978         setOpCode (OP_ARETURN);
979         return this;
980     case 'I':
981     case 'B':
982     case 'Z':
983     case 'C':
984     case 'S':
985         setOpCode (OP_IRETURN);
986         return this;
987     case 'J':
988         setOpCode (OP_LRETURN);
989         return this;
990     case 'F':
991         setOpCode (OP_FRETURN);
992         return this;
993     case 'D':
994         setOpCode (OP_DRETURN);
995         return this;
996     case 'V':
997         setOpCode (OP_RETURN);
998         return this;
999     }
1000
1001    return null;
1002    }
1003
1004    /** Set this to an ALOAD
1005     * @param lvt index
1006     * @return a reference to this
1007     */

1008    public Instruction setAload(int lvt)
1009    {
1010    setOpCode(OP_ALOAD);
1011    setLvtIndex(lvt);
1012    initialize();
1013    return this;
1014    }
1015
1016    /** Set this to a ret
1017     * @param lvt index
1018     * @return a reference to this
1019     */

1020    public Instruction setRet(int lvt)
1021    {
1022    setOpCode(OP_RET);
1023    setLvtIndex(lvt);
1024    initialize();
1025    return this;
1026    }
1027
1028    /** Set this to an ILOAD
1029     * @param lvt index
1030     * @return a reference to this
1031     */

1032    public Instruction setIload(int lvt) {
1033    initialize();
1034    setOpCode(OP_ILOAD);
1035    setLvtIndex(lvt);
1036    return this;
1037    }
1038
1039    /** Set this to a DLOAD
1040     * @param lvt index
1041     * @return a reference to this
1042     */

1043    public Instruction setDload(int lvt) {
1044    initialize();
1045    setOpCode(OP_DLOAD);
1046    setLvtIndex( lvt );
1047    return this;
1048    }
1049
1050    /** Set this to an FLOAD
1051     * @param lvt index
1052     * @return a reference to this
1053     */

1054    public Instruction setFload(int lvt) {
1055    initialize();
1056    setOpCode(OP_FLOAD);
1057    setLvtIndex(lvt);
1058    return this;
1059    }
1060
1061    /** Set this to an LLOAD
1062     * @param lvt index
1063     * @return a reference to this
1064     */

1065    public Instruction setLload(int lvt) {
1066    initialize();
1067    setOpCode(OP_LLOAD);
1068    setLvtIndex(lvt);
1069    return this;
1070    }
1071
1072    /** Set this to an ISTORE
1073     * @param lvt index
1074     * @return a reference to this
1075     */

1076    public Instruction setIstore(int lvt) {
1077    initialize();
1078    setOpCode(OP_ISTORE);
1079    setLvtIndex(lvt);
1080    return this;
1081    }
1082
1083    /** Set this to an IASTORE
1084     * @return a reference to this
1085     */

1086    public Instruction setIastore() {
1087    initialize();
1088    setOpCode(OP_IASTORE);
1089    return this;
1090    }
1091
1092    /** Set this to an IALOAD
1093     * @return a reference to this
1094     */

1095    public Instruction setIaload() {
1096    initialize();
1097    setOpCode(OP_IALOAD);
1098    return this;
1099    }
1100
1101    /** Set this to an AASTORE
1102     * @return a reference to this
1103     */

1104    public Instruction setAastore() {
1105    initialize();
1106    setOpCode(OP_AASTORE);
1107    return this;
1108    }
1109
1110    /** Set this to an AALOAD
1111     * @return a reference to this
1112     */

1113    public Instruction setAaload() {
1114    initialize();
1115    setOpCode(OP_AALOAD);
1116    return this;
1117    }
1118
1119    /** Set this to an ARRAYLENGTH
1120     * @return a reference to this
1121     */

1122    public Instruction setArrayLength () {
1123    initialize();
1124    setOpCode (OP_ARRAYLENGTH);
1125    return this;
1126    }
1127
1128    /** Set this to an ISUB
1129     * @return a reference to this
1130     */

1131    public Instruction setIsub() {
1132    initialize();
1133    setOpCode (OP_ISUB);
1134    return this;
1135    }
1136
1137    /** Set this to an IINC
1138     * @param lvt index
1139     * @param inc increment immediate
1140     * @return a reference to this
1141     */

1142    public Instruction setIinc (int lvt, int inc) {
1143    initialize();
1144    setOpCode (OP_IINC);
1145    setLvtIndex (lvt);
1146    setImmediate (inc);
1147    return this;
1148    }
1149
1150    /** Set this to an LSTORE
1151     * @param lvt index
1152     * @return a reference to this
1153     */

1154    public Instruction setLstore(int lvt) {
1155    initialize();
1156    setOpCode(OP_LSTORE);
1157    setLvtIndex(lvt);
1158    return this;
1159    }
1160
1161    /** Set this to an FSTORE
1162     * @param lvt index
1163     * @return a reference to this
1164     */

1165    public Instruction setFstore(int lvt) {
1166    initialize();
1167    setOpCode(OP_FSTORE);
1168    setLvtIndex(lvt);
1169    return this;
1170    }
1171
1172    /** Set this to a DSTORE
1173     * @param lvt index
1174     * @return a reference to this
1175     */

1176    public Instruction setDstore(int lvt) {
1177    initialize();
1178    setOpCode(OP_DSTORE);
1179    setLvtIndex(lvt);
1180    return this;
1181    }
1182
1183    /** Set this to an ASTORE
1184     * @param lvt index
1185     * @return a reference to this
1186     */

1187    public Instruction setAstore(int lvt) {
1188    initialize();
1189    setOpCode(OP_ASTORE);
1190    setLvtIndex(lvt);
1191    return this;
1192    }
1193
1194    /** Set this to the correct STORE opcode depending on type
1195     * @param t type
1196     * @param lvt index
1197     * @return a reference to this
1198     */

1199    public Instruction setStore(Type t, int lvt) {
1200    initialize();
1201    setLvtIndex(lvt);
1202
1203    if (t.arraydepth > 0) {
1204        setOpCode (OP_ASTORE);
1205        return this;
1206    }
1207
1208    switch (t.base) {
1209    case 'Z':
1210    case 'C':
1211    case 'B':
1212    case 'S':
1213    case 'I':
1214        setOpCode(OP_ISTORE);
1215        break;
1216    case 'J':
1217        setOpCode(OP_LSTORE);
1218        break;
1219    case 'F':
1220        setOpCode(OP_FSTORE);
1221        break;
1222    case 'D':
1223        setOpCode(OP_DSTORE);
1224        break;
1225    default:
1226        setOpCode(OP_ASTORE);
1227        break;
1228    }
1229
1230    return this;
1231    }
1232
1233    /** Set this to a SWAP
1234     * @return a reference to this
1235     */

1236    public Instruction setSwap() {
1237    initialize();
1238    setOpCode( OP_SWAP );
1239    return this;
1240    }
1241
1242    /**
1243     * Initialize an Instruction object as an "ifeq" instruction.
1244     * @param target The instruction to branch to.
1245     * @return a reference to this instance.
1246     */

1247    public Instruction setIfeq(Instruction target) {
1248    setOpCode(OP_IFEQ);
1249    setBranchTarget(new BranchTarget());
1250    branchTarget().instr = target;
1251    return this;
1252    }
1253
1254    /** Make this instruction an IFNE.
1255     * @param target the instruction that this one goes to.
1256     * @return a reference to this instance.
1257     */

1258    public Instruction setIfne (Instruction target) {
1259    setOpCode(OP_IFNE);
1260    setBranchTarget(new BranchTarget());
1261    branchTarget().instr = target;
1262    return this;
1263    }
1264
1265    /** Make this instruction an IFEQ.
1266     * @return a reference to this instance.
1267     */

1268    public Instruction setIfeq() {
1269    setOpCode(OP_IFEQ);
1270    setBranchTarget(new BranchTarget());
1271    return this;
1272    }
1273
1274    /** Make this instruction an IFNE.
1275     * @return a reference to this instance.
1276     */

1277    public Instruction setIfne() {
1278    setOpCode(OP_IFNE);
1279    setBranchTarget(new BranchTarget());
1280    return this;
1281    }
1282
1283    /** Make this instruction an IFLT.
1284     * @param target the instruction that this one goes to.
1285     * @return a reference to this instance.
1286     */

1287    public Instruction setIflt(Instruction ins) {
1288    setOpCode(OP_IFLT);
1289    setBranchTarget(new BranchTarget());
1290    branchTarget().instr = ins;
1291    return this;
1292    }
1293
1294    /** Make this instruction an IF_ICMPLE.
1295     * @param target the instruction that this one goes to.
1296     * @return a reference to this instance.
1297     */

1298    public Instruction setIfIcmple(Instruction target) {
1299    setOpCode(OP_IF_ICMPLE);
1300    setBranchTarget(new BranchTarget());
1301    branchTarget().instr = target;
1302    return this;
1303    }
1304
1305    /** Make this instruction an IF_ICMPLE.
1306     * @return a reference to this instance.
1307     */

1308    public Instruction setIfIcmple() {
1309    setOpCode(OP_IF_ICMPLE);
1310    setBranchTarget(new BranchTarget());
1311    return this;
1312    }
1313
1314    /** Make this instruction an IF_ICMPNE.
1315     * @param target the instruction that this one goes to.
1316     * @return a reference to this instance.
1317     */

1318    public Instruction setIfIcmpne(Instruction target) {
1319    setOpCode(OP_IF_ICMPNE);
1320    setBranchTarget(new BranchTarget());
1321    branchTarget().instr = target;
1322    return this;
1323    }
1324
1325    /** Make this instruction an IF_ICMPNE.
1326     * @return a reference to this instance.
1327     */

1328    public Instruction setIfIcmpne() {
1329    setOpCode(OP_IF_ICMPNE);
1330    setBranchTarget(new BranchTarget());
1331    return this;
1332    }
1333
1334    /** Make this instruction an IF_ICMPEQ.
1335     * @param target the instruction that this one goes to.
1336     * @return a reference to this instance.
1337     */

1338    public Instruction setIfIcmpeq(Instruction target) {
1339    setOpCode(OP_IF_ICMPEQ);
1340    setBranchTarget(new BranchTarget());
1341    branchTarget().instr = target;
1342    return this;
1343    }
1344
1345    /** Make this instruction an IF_ICMPEQ.
1346     * @return a reference to this instance.
1347     */

1348    public Instruction setIfIcmpeq() {
1349    setOpCode(OP_IF_ICMPEQ);
1350    setBranchTarget(new BranchTarget());
1351    return this;
1352    }
1353
1354    /** Make this instruction an IF_ICMPGE.
1355     * @param ins the instruction that this one goes to.
1356     * @return a reference to this instance.
1357     */

1358    public Instruction setIfIcmpge(Instruction ins) {
1359    setOpCode(OP_IF_ICMPGE);
1360    setBranchTarget(new BranchTarget());
1361    branchTarget().instr = ins;
1362    return this;
1363    }
1364
1365    /** Make this instruction an IF_ICMPGT.
1366     * @param target the instruction that this one goes to.
1367     * @return a reference to this instance.
1368     */

1369    public Instruction setIfIcmpgt(Instruction target) {
1370    setOpCode(OP_IF_ICMPGT);
1371    setBranchTarget(new BranchTarget());
1372    branchTarget().instr = target;
1373    return this;
1374    }
1375
1376    /** Make this instruction an IF_ICMPGT.
1377     * @return a reference to this instance.
1378     */

1379    public Instruction setIfIcmpgt() {
1380    setOpCode(OP_IF_ICMPGT);
1381    setBranchTarget(new BranchTarget());
1382    return this;
1383    }
1384
1385    /** Make this instruction a GOTO to the given instruction.
1386     * @param target the instruction that this one goes to.
1387     * @return a reference to this instance.
1388     */

1389    public Instruction setGoto (Instruction target)
1390    {
1391    initialize();
1392    setOpCode (OP_GOTO);
1393    setBranchTarget (new BranchTarget ());
1394    branchTarget().instr = target;
1395    return this;
1396    }
1397
1398    /** Make this instruction a GOTO to the given switch block.
1399     * @param target the switch block that this one goes to.
1400     * @return a reference to this instance.
1401     */

1402    public Instruction setGoto (Block target)
1403    {
1404    initialize();
1405    setOpCode (OP_GOTO);
1406    setBranchTarget (new BranchTarget ());
1407    branchTarget().block = target;
1408    return this;
1409    }
1410
1411    /** Make this instruction a TABLESWITCH.
1412     * @return a reference to this instance.
1413     */

1414    public Instruction setTableSwitch () {
1415    initialize();
1416    setOpCode (OP_TABLESWITCH);
1417    setBranchTarget (new BranchTarget ());
1418    return this;
1419    }
1420
1421    /** Make this instruction a LOOKUPSWITCH.
1422     * @return a reference to this instance.
1423     */

1424    public Instruction setLookupSwitch () {
1425    initialize();
1426    setOpCode (OP_LOOKUPSWITCH);
1427    setBranchTarget (new BranchTarget ());
1428    return this;
1429    }
1430
1431    /** Constructor.
1432     */

1433    public Instruction () { }
1434
1435    void setVarAccess(int opc) {
1436    switch(opc) {
1437    case OP_ILOAD_0:
1438    case OP_ILOAD_1:
1439    case OP_ILOAD_2:
1440    case OP_ILOAD_3:
1441        setOpCode( OP_ILOAD );
1442        setLvtIndex( opc - OP_ILOAD_0 );
1443        break;
1444    case OP_FLOAD_0:
1445    case OP_FLOAD_1:
1446    case OP_FLOAD_2:
1447    case OP_FLOAD_3:
1448        setOpCode( OP_FLOAD );
1449        setLvtIndex( opc - OP_FLOAD_0 );
1450        break;
1451    case OP_LLOAD_0:
1452    case OP_LLOAD_1:
1453    case OP_LLOAD_2:
1454    case OP_LLOAD_3:
1455        setOpCode( OP_LLOAD );
1456        setLvtIndex( opc - OP_LLOAD_0 );
1457        break;
1458    case OP_DLOAD_0:
1459    case OP_DLOAD_1:
1460    case OP_DLOAD_2:
1461    case OP_DLOAD_3:
1462        setOpCode( OP_DLOAD );
1463        setLvtIndex( opc - OP_DLOAD_0 );
1464        break;
1465    case OP_ALOAD_0:
1466    case OP_ALOAD_1:
1467    case OP_ALOAD_2:
1468    case OP_ALOAD_3:
1469        setOpCode( OP_ALOAD );
1470        setLvtIndex( opc - OP_ALOAD_0 );
1471        break;
1472    case OP_ISTORE_0:
1473    case OP_ISTORE_1:
1474    case OP_ISTORE_2:
1475    case OP_ISTORE_3:
1476        setOpCode( OP_ISTORE );
1477        setLvtIndex( opc - OP_ISTORE_0 );
1478        break;
1479    case OP_FSTORE_0:
1480    case OP_FSTORE_1:
1481    case OP_FSTORE_2:
1482    case OP_FSTORE_3:
1483        setOpCode( OP_FSTORE );
1484        setLvtIndex( opc - OP_FSTORE_0 );
1485        break;
1486    case OP_LSTORE_0:
1487    case OP_LSTORE_1:
1488    case OP_LSTORE_2:
1489    case OP_LSTORE_3:
1490        setOpCode( OP_LSTORE );
1491        setLvtIndex( opc - OP_LSTORE_0 );
1492        break;
1493    case OP_DSTORE_0:
1494    case OP_DSTORE_1:
1495    case OP_DSTORE_2:
1496    case OP_DSTORE_3:
1497        setOpCode( OP_DSTORE );
1498        setLvtIndex( opc - OP_DSTORE_0 );
1499        break;
1500    case OP_ASTORE_0:
1501    case OP_ASTORE_1:
1502    case OP_ASTORE_2:
1503    case OP_ASTORE_3:
1504        setOpCode( OP_ASTORE );
1505        setLvtIndex( opc - OP_ASTORE_0 );
1506        break;
1507    }
1508    }
1509
1510
1511    /**
1512     * Constructor parses a JVM bytecode and any in-line data and
1513     * creates a single Instruction object.
1514     *
1515     * @param code An array of JVM bytecodes.
1516     * @param index Where in the array to recognize the instruction.
1517     * @return size in bytes of the instruction we just read.
1518     */

1519    public int readFile (DataInputStream dataIn,
1520             int index,
1521             ConstantPool constantPool)
1522    throws ClassFileException, IOException {
1523    initialize();
1524    int size = -1; /* error check */
1525    int i;
1526    int switchVal = dataIn.readUnsignedByte();
1527    setRealOpCode( switchVal );
1528    switch(switchVal) {
1529    case OP_NOP:
1530    case OP_MONITORENTER:
1531    case OP_MONITOREXIT:
1532    case OP_IRETURN:
1533    case OP_LRETURN:
1534    case OP_FRETURN:
1535    case OP_DRETURN:
1536    case OP_ARETURN:
1537    case OP_RETURN:
1538    case OP_ATHROW:
1539    case OP_ACONST_NULL:
1540    case OP_POP:
1541    case OP_POP2:
1542    case OP_DUP:
1543    case OP_DUP_X1:
1544    case OP_DUP_X2:
1545    case OP_DUP2:
1546    case OP_DUP2_X1:
1547    case OP_DUP2_X2:
1548    case OP_SWAP:
1549    case OP_IADD:
1550    case OP_LADD:
1551    case OP_FADD:
1552    case OP_DADD:
1553    case OP_ISUB:
1554    case OP_LSUB:
1555    case OP_FSUB:
1556    case OP_DSUB:
1557    case OP_IMUL:
1558    case OP_LMUL:
1559    case OP_FMUL:
1560    case OP_DMUL:
1561    case OP_IDIV:
1562    case OP_LDIV:
1563    case OP_FDIV:
1564    case OP_DDIV:
1565    case OP_IREM:
1566    case OP_LREM:
1567    case OP_FREM:
1568    case OP_DREM:
1569    case OP_INEG:
1570    case OP_LNEG:
1571    case OP_FNEG:
1572    case OP_DNEG:
1573    case OP_ISHL:
1574    case OP_LSHL:
1575    case OP_ISHR:
1576    case OP_LSHR:
1577    case OP_IUSHR:
1578    case OP_LUSHR:
1579    case OP_IAND:
1580    case OP_LAND:
1581    case OP_IOR:
1582    case OP_LOR:
1583    case OP_IXOR:
1584    case OP_LXOR:
1585    case OP_LCMP:
1586    case OP_FCMPG:
1587    case OP_FCMPL:
1588    case OP_DCMPG:
1589    case OP_DCMPL:
1590    case OP_I2B:
1591    case OP_I2C:
1592    case OP_I2D:
1593    case OP_L2I:
1594    case OP_L2F:
1595    case OP_L2D:
1596    case OP_F2I:
1597    case OP_F2L:
1598    case OP_F2D:
1599    case OP_D2I:
1600    case OP_D2L:
1601    case OP_D2F:
1602    case OP_I2F:
1603    case OP_I2L:
1604    case OP_I2S:
1605    case OP_IALOAD:
1606    case OP_LALOAD:
1607    case OP_FALOAD:
1608    case OP_DALOAD:
1609    case OP_AALOAD:
1610    case OP_CALOAD:
1611    case OP_SALOAD:
1612    case OP_BALOAD:
1613    case OP_IASTORE:
1614    case OP_LASTORE:
1615    case OP_FASTORE:
1616    case OP_DASTORE:
1617    case OP_AASTORE:
1618    case OP_BASTORE:
1619    case OP_CASTORE:
1620    case OP_SASTORE:
1621    case OP_ARRAYLENGTH:
1622        setOpCode(switchVal);
1623        size = 1;
1624        break;
1625                
1626    case OP_WIDE: {
1627        setOpCode( dataIn.readUnsignedByte() );
1628        setLvtIndex ( dataIn.readUnsignedShort() );
1629        size = 4;
1630        switch(opCode()) {
1631        case OP_ILOAD:
1632        case OP_FLOAD:
1633        case OP_ALOAD:
1634        case OP_LLOAD:
1635        case OP_DLOAD:
1636        case OP_RET:
1637        case OP_ISTORE:
1638        case OP_FSTORE:
1639        case OP_ASTORE:
1640        case OP_LSTORE:
1641        case OP_DSTORE:
1642        break;
1643        case OP_IINC:
1644        setImmediate( dataIn.readUnsignedShort() );
1645        size = 6;
1646        break;
1647        default:
1648        throw new ClassFileException ("wide instruction specifies bad opcode");
1649        }
1650        break;
1651    }
1652                
1653    case OP_NEW:
1654    case OP_ANEWARRAY:
1655    case OP_CHECKCAST:
1656    case OP_INSTANCEOF:
1657        setOpCode(switchVal);
1658        i = dataIn.readUnsignedShort();
1659        setCpItemIndex( i );
1660        setClassRef( constantPool.cpClassAt(i).string() );
1661        size = 3;
1662        break;
1663                
1664    case OP_NEWARRAY:
1665        setOpCode (switchVal);
1666        setImmediate( dataIn.readUnsignedByte() );
1667        size = 2;
1668        break;
1669                
1670    case OP_MULTIANEWARRAY:
1671        setOpCode(switchVal);
1672        i = dataIn.readUnsignedShort();
1673        setClassRef( constantPool.cpClassAt(i).string() );
1674        setCpItemIndex( i );
1675        setImmediate( dataIn.readUnsignedByte() );
1676        size = 4;
1677        break;
1678                
1679    case OP_RET:
1680        setOpCode( switchVal );
1681        setLvtIndex( dataIn.readUnsignedByte() );
1682        size = 2;
1683        break;
1684                
1685                
1686    case OP_INVOKESPECIAL:
1687    case OP_INVOKEVIRTUAL:
1688    case OP_INVOKESTATIC: {
1689        setOpCode( switchVal );
1690        i = dataIn.readUnsignedShort();
1691        CpMethodRef cp = constantPool.cpMethodRefAt(i);
1692        setClassRef(cp.classname());
1693        setElemName(cp.name());
1694        setDescriptor(cp.descriptor());
1695        size = 3;
1696        break;
1697    }
1698                        
1699    case OP_INVOKEINTERFACE: {
1700        setOpCode( switchVal );
1701        i = dataIn.readUnsignedShort();
1702
1703        CpMethodRef cp = constantPool.cpMethodRefAt(i);
1704        setClassRef(cp.classname());
1705        setElemName(cp.name());
1706        setDescriptor(cp.descriptor());
1707        /* The count byte is the number of arguments to the method
1708           referenced. It is redundant with the info in the
1709           methodref structure, but is present for historical
1710           reasons. Not currently used here. */

1711        int argCount = dataIn.readUnsignedByte();
1712        if (argCount != descriptor().count()) {
1713        StringBuffer JavaDoc msg = new StringBuffer JavaDoc ("argCount is wrong in interface: ");
1714        msg.append (argCount);
1715        msg.append (", ");
1716        msg.append (descriptor().count());
1717        msg.append (", ");
1718        msg.append (cp.toString ());
1719        throw new ClassFileException(msg.toString ());
1720        }
1721
1722        /* A placeholder (zero) byte also follows the instruction.
1723           It isn't used, but must be reserved for compatibility
1724           with some Sun implememtations that replace this
1725           instruction. */

1726        dataIn.readUnsignedByte();
1727        size = 5;
1728        break;
1729    }
1730                
1731                
1732    case OP_IFEQ: /* test an int against zero */
1733    case OP_IFNE:
1734    case OP_IFLT:
1735    case OP_IFGE:
1736    case OP_IFGT:
1737    case OP_IFLE:
1738    case OP_IF_ICMPEQ: /* test two ints on the stack */
1739    case OP_IF_ICMPNE:
1740    case OP_IF_ICMPLT:
1741    case OP_IF_ICMPGE:
1742    case OP_IF_ICMPGT:
1743    case OP_IF_ICMPLE:
1744    case OP_IF_ACMPEQ: /* test two references on the stack */
1745    case OP_IF_ACMPNE:
1746    case OP_JSR:
1747    case OP_IFNULL:
1748    case OP_IFNONNULL:
1749    case OP_GOTO:
1750        setOpCode( switchVal );
1751        setBranchTarget(new BranchTarget());
1752        branchTarget().offset = dataIn.readShort();
1753        size = 3;
1754        break;
1755                
1756    case OP_GOTO_W:
1757        //Jbet.warn.println ("WARNING: ***** wide jumps in input");
1758
setOpCode( OP_GOTO );
1759        setBranchTarget( new BranchTarget() );
1760        branchTarget().offset = dataIn.readInt();
1761        size = 5;
1762        break;
1763                
1764    case OP_JSR_W:
1765        //Jbet.warn.println ("WARNING: ***** wide jumps in input");
1766
setOpCode( OP_JSR );
1767        setBranchTarget( new BranchTarget() );
1768        branchTarget().offset = dataIn.readInt();
1769        size = 5;
1770        break;
1771                
1772    case OP_TABLESWITCH: {
1773        /*
1774         * This is a complex instruction used for large switch
1775         * statements (and possibly other places too). It reads a
1776         * table of 32-bit addresses (to jump to) and uses a
1777         * parameter, on the operand stack, to decide which of the
1778         * addresses to jump to. The table of addresses is
1779         * actually in-line data following the tableswitch opcode.
1780         * It's a variable-length table. The following code
1781         * calculates how much space is consumed by the table, and
1782         * builds an array of addresses.
1783         */

1784        setOpCode( switchVal );
1785        size = 1;
1786                
1787        /* skip the zero-padded bytes that establish 4-byte
1788         * allignment of following data */

1789        for (int pIndex = index+1; (pIndex % 4) != 0; pIndex++) {
1790        dataIn.readUnsignedByte();
1791        size++;
1792        }
1793        /*
1794         * Read in the default relative jump addr, and the
1795         * bounds of the jump table.
1796         */

1797        setBranchTarget( new BranchTarget() );
1798        branchTarget().offset = dataIn.readInt();
1799        int lowBound = dataIn.readInt();
1800        int highBound = dataIn.readInt();
1801        size += 12;
1802                
1803        /*
1804         * Now read in the variable-length array of 32-bit
1805         * jump addresses.
1806         */

1807        setSwitchArray ( new BranchTarget[(highBound-lowBound) + 1] );
1808        for (i=0; i<switchArray().length; i++) {
1809        switchArray()[i] = new BranchTarget();
1810        switchArray()[i].offset = dataIn.readInt();
1811        size += 4;
1812        }
1813                
1814        setImmediate( lowBound );
1815        break;
1816    }
1817    case OP_LOOKUPSWITCH: {
1818        setOpCode( switchVal );
1819        size = 1;
1820                
1821        /* skip the zero-padded bytes that establish 4-byte
1822         * allignment of following data */

1823        for (int pIndex = index+1; (pIndex % 4) != 0; pIndex++) {
1824        dataIn.readUnsignedByte();
1825        size++;
1826        }
1827        /*
1828         * Read in the default relative (default) jump addr, and the
1829         * number of match-offset pairs.
1830         */

1831        setBranchTarget( new BranchTarget() );
1832        branchTarget().offset = dataIn.readInt();
1833        int nPairs = dataIn.readInt();
1834        size += 8;
1835                
1836        setSwitchArray (new BranchTarget[nPairs] );
1837        for (int kIndex=0; kIndex<switchArray().length; kIndex++) {
1838        switchArray()[kIndex] = new BranchTarget();
1839        switchArray()[kIndex].key = dataIn.readInt();
1840        switchArray()[kIndex].offset = dataIn.readInt();
1841        size += 8;
1842        }
1843        break;
1844    }
1845                
1846    case OP_ICONST_M1:
1847    case OP_ICONST_0:
1848    case OP_ICONST_1:
1849    case OP_ICONST_2:
1850    case OP_ICONST_3:
1851    case OP_ICONST_4:
1852    case OP_ICONST_5:
1853        setOpCode( AOP_IPUSH );
1854        setImmediate( switchVal - OP_ICONST_0 );
1855        size = 1;
1856        break;
1857                
1858    case OP_FCONST_0:
1859    case OP_FCONST_1:
1860    case OP_FCONST_2:
1861        setOpCode( AOP_FPUSH );
1862        setImmediate_f( (float) (switchVal - OP_FCONST_0) );
1863        size = 1;
1864        break;
1865                
1866    case OP_LCONST_0:
1867    case OP_LCONST_1:
1868        setOpCode( AOP_LPUSH );
1869        setImmediate( switchVal - OP_LCONST_0 );
1870        size = 1;
1871        break;
1872                
1873    case OP_DCONST_0:
1874        case OP_DCONST_1 :
1875        setOpCode( AOP_DPUSH );
1876        setImmediate_f( (double) (switchVal - OP_DCONST_0) );
1877        size = 1;
1878        break;
1879                
1880        case OP_LDC: {
1881        i = dataIn.readUnsignedByte() ;
1882        setCpItemIndex( i );
1883        CpEntry cpe = constantPool.elementAt(i);
1884        if (cpe instanceof CpInteger) {
1885        setOpCode( AOP_IPUSH );
1886        setImmediate( ((CpInteger)cpe).value );
1887        } else if (cpe instanceof CpFloat) {
1888        setOpCode( AOP_FPUSH );
1889        setImmediate_f( ((CpFloat)cpe).value );
1890        } else if (cpe instanceof CpString) {
1891        setOpCode( AOP_SPUSH );
1892        setImmediate_s( constantPool.stringAt(i) );
1893        } else
1894        throw new ClassFileException
1895            ("attempt to ldc something that is not a Float, Int, or String");
1896        size = 2;
1897        break;
1898    }
1899                
1900                
1901    case OP_LDC_W: {
1902        i = dataIn.readUnsignedShort();
1903        setCpItemIndex( i );
1904        CpEntry cpe = constantPool.elementAt(i);
1905        if (cpe instanceof CpInteger) {
1906        setOpCode( AOP_IPUSH );
1907        setImmediate( ((CpInteger)cpe).value );
1908        } else if (cpe instanceof CpFloat) {
1909        setOpCode( AOP_FPUSH );
1910        setImmediate_f( ((CpFloat)cpe).value );
1911        } else if (cpe instanceof CpString) {
1912        setOpCode( AOP_SPUSH );
1913        setImmediate_s( constantPool.stringAt(i) );
1914        } else
1915        throw new ClassFileException
1916            ("attempt to ldc_w something that is not a Float, Int, or String");
1917        size = 3;
1918        break;
1919    }
1920                
1921    case OP_LDC2_W: {
1922        i = dataIn.readUnsignedShort();
1923        setCpItemIndex( i );
1924        CpEntry cpe = constantPool.elementAt(i);
1925        if (cpe instanceof CpLong) {
1926        setOpCode( AOP_LPUSH );
1927        setImmediate_l( ((CpLong)cpe).value );
1928        } else if (cpe instanceof CpDouble) {
1929        setOpCode( AOP_DPUSH );
1930        setImmediate_f( ((CpDouble)cpe).value );
1931        } else
1932        throw new ClassFileException
1933            ("attempt to ldc_2w something that is not a long or double\n");
1934                
1935        size = 3;
1936        break;
1937    }
1938                
1939    case OP_BIPUSH:
1940        setOpCode( AOP_IPUSH );
1941        setImmediate( dataIn.readByte() );
1942        size = 2;
1943        break;
1944                
1945    case OP_SIPUSH:
1946        setOpCode( AOP_IPUSH );
1947        setImmediate( dataIn.readShort() );
1948        size = 3;
1949        break;
1950                
1951    case OP_ILOAD:
1952    case OP_FLOAD:
1953    case OP_LLOAD:
1954    case OP_DLOAD:
1955    case OP_ALOAD:
1956        setOpCode( switchVal );
1957        setLvtIndex( dataIn.readUnsignedByte() );
1958        size = 2;
1959        break;
1960                
1961    case OP_ISTORE:
1962    case OP_FSTORE:
1963    case OP_LSTORE:
1964    case OP_DSTORE:
1965    case OP_ASTORE:
1966        setOpCode( switchVal );
1967        setLvtIndex( dataIn.readUnsignedByte() );
1968        size = 2;
1969        break;
1970
1971    case OP_ILOAD_0:
1972    case OP_ILOAD_1:
1973    case OP_ILOAD_2:
1974    case OP_ILOAD_3:
1975    case OP_FLOAD_0:
1976    case OP_FLOAD_1:
1977    case OP_FLOAD_2:
1978    case OP_FLOAD_3:
1979    case OP_LLOAD_0:
1980    case OP_LLOAD_1:
1981    case OP_LLOAD_2:
1982    case OP_LLOAD_3:
1983    case OP_DLOAD_0:
1984    case OP_DLOAD_1:
1985    case OP_DLOAD_2:
1986    case OP_DLOAD_3:
1987    case OP_ALOAD_0:
1988    case OP_ALOAD_1:
1989    case OP_ALOAD_2:
1990    case OP_ALOAD_3:
1991    case OP_ISTORE_0:
1992    case OP_ISTORE_1:
1993    case OP_ISTORE_2:
1994    case OP_ISTORE_3:
1995    case OP_FSTORE_0:
1996    case OP_FSTORE_1:
1997    case OP_FSTORE_2:
1998    case OP_FSTORE_3:
1999    case OP_LSTORE_0:
2000    case OP_LSTORE_1:
2001    case OP_LSTORE_2:
2002    case OP_LSTORE_3:
2003    case OP_DSTORE_0:
2004    case OP_DSTORE_1:
2005    case OP_DSTORE_2:
2006    case OP_DSTORE_3:
2007    case OP_ASTORE_0:
2008    case OP_ASTORE_1:
2009    case OP_ASTORE_2:
2010    case OP_ASTORE_3:
2011        setVarAccess( switchVal );
2012        size = 1;
2013        break;
2014                
2015    case OP_GETSTATIC:
2016    case OP_PUTSTATIC:
2017    case OP_GETFIELD:
2018    case OP_PUTFIELD: {
2019        setOpCode( switchVal );
2020        i = dataIn.readUnsignedShort();
2021        CpFieldRef cp = constantPool.cpFieldRefAt(i) ;
2022        setClassRef(cp.classname());
2023        setElemName(cp.name());
2024        setType(cp.type());
2025        size = 3;
2026        break;
2027    }
2028                
2029                
2030    case OP_IINC:
2031        setOpCode( switchVal );
2032        setLvtIndex( dataIn.readUnsignedByte() );
2033        setImmediate( dataIn.readByte() );
2034        size = 3;
2035        break;
2036                
2037                
2038    default:
2039        throw new ClassFileException
2040        ("non-existent opcode: " + Integer.toString(switchVal));
2041    } // switch
2042

2043    if (size == -1)
2044        throw new ClassFileException ("size was not set, opcode: "
2045                      + opCode());
2046                
2047    return size;
2048                    
2049    } // readFile
2050

2051
2052    int generate_loadstore (DataOutputStream dataOut, int op_0)
2053    throws IOException {
2054    if (lvtIndex() <= 3) {
2055        dataOut.writeByte ( op_0 + lvtIndex() );
2056        return 1;
2057    } else if (lvtIndex() <= 255 ) {
2058        dataOut.writeByte( opCode() );
2059        dataOut.writeByte( lvtIndex() );
2060        return 2;
2061    } else {
2062        dataOut.writeByte( OP_WIDE );
2063        dataOut.writeByte( opCode() );
2064        dataOut.writeShort( lvtIndex() );
2065        return 4;
2066    }
2067    }
2068
2069    /** Called from Snippit.resolveConstants() for each instruction.
2070     * Calls setRealOpCode() or setCpItemIndex.
2071     * It does not setRealOpCode for goto or jsr,
2072     * i.e. decide whether something is a longjump or not.
2073     * that is left to Snippit.resolveBranches().
2074     * @param constantPool the constant pool
2075     */

2076    void resolveConstants (ConstantPool constantPool) {
2077    setCpItemIndex (-1);
2078    switch (opCode()) {
2079    case OP_ILOAD:
2080    case OP_FLOAD:
2081    case OP_LLOAD:
2082    case OP_DLOAD:
2083    case OP_ALOAD:
2084    case OP_ISTORE:
2085    case OP_FSTORE:
2086    case OP_LSTORE:
2087    case OP_DSTORE:
2088    case OP_ASTORE:
2089        //FIXME this should check if it could be fooload_bar instead
2090
if (realOpCode() == -1)
2091        setRealOpCode( opCode() );
2092        break;
2093
2094    case OP_NEW:
2095    case OP_ANEWARRAY:
2096    case OP_MULTIANEWARRAY:
2097    case OP_CHECKCAST:
2098    case OP_INSTANCEOF:
2099        setCpItemIndex ( constantPool.internClass(classRef()) );
2100        break;
2101        
2102    case OP_INVOKESPECIAL:
2103    case OP_INVOKEVIRTUAL:
2104    case OP_INVOKESTATIC:
2105        setCpItemIndex ( constantPool.internMethodRef
2106                 (classRef(), elemName(), descriptor()) );
2107        break;
2108
2109    case OP_INVOKEINTERFACE:
2110        setCpItemIndex ( constantPool.internInterfaceMethodRef
2111                 (classRef(), elemName(), descriptor()) );
2112        break;
2113
2114    case OP_GETSTATIC:
2115    case OP_PUTSTATIC:
2116    case OP_GETFIELD:
2117    case OP_PUTFIELD: {
2118        int i = cpItemIndex();
2119        setCpItemIndex ( constantPool.internFieldRef
2120                 (classRef(), elemName(), type()) );
2121        break;
2122    }
2123
2124    case AOP_IPUSH: {
2125        int rop = realOpCode();
2126        boolean nohint = rop == -1;
2127        if (nohint && -1 <= immediate() && immediate() <= 5 ) {
2128        setRealOpCode( OP_ICONST_0 + immediate() );
2129        } else if (nohint && Byte.MIN_VALUE <= immediate() && immediate() <= Byte.MAX_VALUE ) {
2130        setRealOpCode( OP_BIPUSH );
2131        } else if (nohint && Short.MIN_VALUE <= immediate() && immediate() <= Short.MAX_VALUE ) {
2132        setRealOpCode( OP_SIPUSH );
2133        } else if (nohint || rop == OP_LDC || rop == OP_LDC_W ) {
2134        int index = constantPool.internInteger( immediate() );
2135        setCpItemIndex(index);
2136        if (index <= 255)
2137            setRealOpCode(OP_LDC);
2138        else
2139            setRealOpCode(OP_LDC_W);
2140        }
2141        break;
2142    }
2143
2144    case AOP_FPUSH: {
2145        int rop = realOpCode();
2146        boolean nohint = rop == -1;
2147        if (nohint && (immediate_f() == 0 || immediate_f() == 1 || immediate_f() == 2)) {
2148        setRealOpCode( OP_FCONST_0 + ((int)immediate_f()) );
2149        } else if (nohint || rop == OP_LDC || rop == OP_LDC_W) {
2150        int index = constantPool.internFloat( (float) immediate_f() );
2151        setCpItemIndex(index);
2152        if (index <= 255)
2153            setRealOpCode(OP_LDC);
2154        else
2155            setRealOpCode(OP_LDC_W);
2156        }
2157        break;
2158    }
2159
2160    case AOP_SPUSH: {
2161        int index = constantPool.internString( immediate_s() );
2162        setCpItemIndex(index);
2163        if (index <= 255)
2164        setRealOpCode(OP_LDC);
2165        else
2166        setRealOpCode(OP_LDC_W);
2167        break;
2168    }
2169
2170    case AOP_DPUSH: {
2171        int rop = realOpCode();
2172        boolean nohint = rop == -1;
2173        if (nohint && (immediate_f() == 0 || immediate_f() == 1) ) {
2174        setRealOpCode( OP_DCONST_0 + ((int)immediate_f()) );
2175        } else if (nohint || rop == OP_LDC2_W) {
2176        int index = constantPool.internDouble( immediate_f() );
2177        setCpItemIndex(index);
2178        setRealOpCode (OP_LDC2_W);
2179        }
2180        break;
2181    }
2182
2183    case AOP_LPUSH: {
2184        int rop = realOpCode();
2185        boolean nohint = rop == -1;
2186        if (nohint && (immediate_l() == 0 || immediate_l() == 1) ) {
2187        setRealOpCode( OP_LCONST_0 + ((int)immediate_l()) );
2188        } else if (nohint || rop == OP_LDC2_W) {
2189
2190        int index = constantPool.internLong( immediate_l() );
2191        setCpItemIndex(index);
2192        setRealOpCode (OP_LDC2_W);
2193        }
2194        break;
2195    }
2196    default:
2197        setRealOpCode( opCode() );
2198    }
2199    } // resolveConstants
2200

2201    /** write the instruction to a file.
2202     * @param dataOut output stream
2203     * @param index size of padding for alignment in tableswitch
2204     * @return size written
2205     */

2206    public int writeFile(DataOutputStream dataOut, int index)
2207    throws RuntimeException JavaDoc, IOException {
2208
2209    int size = 0;
2210    switch(opCode()) {
2211    case OP_IADD:
2212    case OP_LADD:
2213    case OP_FADD:
2214    case OP_DADD:
2215    case OP_ISUB:
2216    case OP_LSUB:
2217    case OP_FSUB:
2218    case OP_DSUB:
2219    case OP_IMUL:
2220    case OP_LMUL:
2221    case OP_FMUL:
2222    case OP_DMUL:
2223    case OP_IDIV:
2224    case OP_LDIV:
2225    case OP_FDIV:
2226    case OP_DDIV:
2227    case OP_IREM:
2228    case OP_LREM:
2229    case OP_FREM:
2230    case OP_DREM:
2231    case OP_INEG:
2232    case OP_LNEG:
2233    case OP_FNEG:
2234    case OP_DNEG:
2235    case OP_ISHL:
2236    case OP_LSHL:
2237    case OP_ISHR:
2238    case OP_LSHR:
2239    case OP_IUSHR:
2240    case OP_LUSHR:
2241    case OP_IAND:
2242    case OP_LAND:
2243    case OP_IOR:
2244    case OP_LOR:
2245    case OP_IXOR:
2246    case OP_LXOR:
2247    case OP_LCMP:
2248    case OP_FCMPG:
2249    case OP_FCMPL:
2250    case OP_DCMPG:
2251    case OP_DCMPL:
2252    case OP_DUP:
2253    case OP_DUP_X1:
2254    case OP_DUP_X2:
2255    case OP_DUP2:
2256    case OP_DUP2_X1:
2257    case OP_DUP2_X2:
2258    case OP_SWAP:
2259    case OP_POP:
2260    case OP_POP2:
2261    case OP_NOP:
2262    case OP_MONITORENTER:
2263    case OP_MONITOREXIT:
2264    case OP_IRETURN:
2265    case OP_LRETURN:
2266    case OP_FRETURN:
2267    case OP_DRETURN:
2268    case OP_ARETURN:
2269    case OP_RETURN:
2270    case OP_ATHROW:
2271    case OP_ACONST_NULL:
2272    case OP_ICONST_M1:
2273    case OP_ICONST_0:
2274    case OP_ICONST_1:
2275    case OP_ICONST_2:
2276    case OP_ICONST_3:
2277    case OP_ICONST_4:
2278    case OP_ICONST_5:
2279    case OP_FCONST_0:
2280    case OP_FCONST_1:
2281    case OP_FCONST_2:
2282    case OP_LCONST_0:
2283    case OP_LCONST_1:
2284    case OP_DCONST_0:
2285    case OP_DCONST_1:
2286    case OP_I2B:
2287    case OP_I2C:
2288    case OP_I2D:
2289    case OP_L2I:
2290    case OP_L2F:
2291    case OP_L2D:
2292    case OP_F2I:
2293    case OP_F2L:
2294    case OP_F2D:
2295    case OP_D2I:
2296    case OP_D2L:
2297    case OP_D2F:
2298    case OP_I2F:
2299    case OP_I2L:
2300    case OP_I2S:
2301    case OP_IALOAD:
2302    case OP_LALOAD:
2303    case OP_FALOAD:
2304    case OP_DALOAD:
2305    case OP_AALOAD:
2306    case OP_CALOAD:
2307    case OP_SALOAD:
2308    case OP_BALOAD:
2309    case OP_IASTORE:
2310    case OP_LASTORE:
2311    case OP_FASTORE:
2312    case OP_DASTORE:
2313    case OP_AASTORE:
2314    case OP_BASTORE:
2315    case OP_CASTORE:
2316    case OP_SASTORE:
2317    case OP_ARRAYLENGTH:
2318        dataOut.writeByte( opCode() );
2319        size = 1;
2320        break;
2321
2322
2323    case OP_NEW:
2324    case OP_ANEWARRAY:
2325    case OP_CHECKCAST:
2326    case OP_INSTANCEOF:
2327        dataOut.writeByte( opCode() );
2328        dataOut.writeShort( cpItemIndex() );
2329        size = 3;
2330        break;
2331
2332    case OP_INVOKESPECIAL:
2333    case OP_INVOKEVIRTUAL:
2334    case OP_INVOKESTATIC:
2335        dataOut.writeByte( opCode() );
2336        dataOut.writeShort( cpItemIndex() );
2337        size = 3;
2338        break;
2339
2340    case OP_GETSTATIC:
2341    case OP_PUTSTATIC:
2342    case OP_GETFIELD:
2343    case OP_PUTFIELD:
2344        dataOut.writeByte( opCode() );
2345        dataOut.writeShort( cpItemIndex() );
2346        size = 3;
2347        break;
2348
2349    case OP_NEWARRAY:
2350        dataOut.writeByte( opCode() );
2351        dataOut.writeByte( immediate() );
2352        size = 2;
2353        break;
2354
2355
2356    case OP_MULTIANEWARRAY:
2357        dataOut.writeByte( opCode() );
2358        dataOut.writeShort( cpItemIndex() );
2359        dataOut.writeByte ( immediate() );
2360        size = 4;
2361        break;
2362
2363
2364    case OP_RET:
2365        dataOut.writeByte( opCode() );
2366        dataOut.writeByte( lvtIndex() );
2367        size = 2;
2368        break;
2369
2370
2371    case OP_INVOKEINTERFACE:
2372        dataOut.writeByte( opCode() );
2373        dataOut.writeShort( cpItemIndex() );
2374        dataOut.writeByte( descriptor().count() );
2375        dataOut.writeByte( 0 );
2376        size = 5;
2377        break;
2378
2379
2380    case OP_IFEQ:
2381    case OP_IFNE:
2382    case OP_IFLT:
2383    case OP_IFGE:
2384    case OP_IFGT:
2385    case OP_IFLE:
2386    case OP_IF_ICMPEQ:
2387    case OP_IF_ICMPNE:
2388    case OP_IF_ICMPLT:
2389    case OP_IF_ICMPGE:
2390    case OP_IF_ICMPGT:
2391    case OP_IF_ICMPLE:
2392    case OP_IF_ACMPEQ:
2393    case OP_IF_ACMPNE:
2394    case OP_IFNULL:
2395    case OP_IFNONNULL:
2396        dataOut.writeByte( opCode() );
2397        dataOut.writeShort( branchTarget().offset );
2398        size = 3;
2399        break;
2400
2401
2402        //case OP_JSR_W:
2403
case OP_JSR:
2404        //if (Short.MIN_VALUE <= branchTarget().offset &&
2405
// branchTarget().offset <= Short.MAX_VALUE) {
2406
if ( realOpCode() == OP_JSR ) {
2407        dataOut.writeByte( OP_JSR );
2408        dataOut.writeShort( branchTarget().offset );
2409        size = 3;
2410        } else {
2411        //Jbet.warn.println ("WARNING: ***** useing wide jumps");
2412
dataOut.writeByte( OP_JSR_W );
2413        dataOut.writeInt( branchTarget().offset );
2414        size = 5;
2415        }
2416        break;
2417
2418
2419        //case OP_GOTO_W:
2420
case OP_GOTO:
2421        //if (Short.MIN_VALUE <= branchTarget().offset &&
2422
//branchTarget().offset <= Short.MAX_VALUE) {
2423
if ( realOpCode() == OP_GOTO ) {
2424        dataOut.writeByte( OP_GOTO );
2425        dataOut.writeShort( branchTarget().offset );
2426        size = 3;
2427        } else {
2428        //Jbet.warn.println ("WARNING: ***** using wide jumps");
2429
dataOut.writeByte( OP_GOTO_W );
2430        dataOut.writeInt( branchTarget().offset );
2431        size = 5;
2432        }
2433        break;
2434
2435
2436    case OP_TABLESWITCH: {
2437        dataOut.writeByte( opCode() );
2438        size = 1;
2439
2440        for (int pIndex = index+1; (pIndex % 4) != 0; pIndex++) {
2441        dataOut.writeByte(0); /* zero these locations */
2442        size++;
2443        }
2444
2445
2446        /*
2447         * Write out the default relative jump addr, and the
2448         * bounds of the jump table.
2449         */

2450
2451        dataOut.writeInt ( branchTarget().offset );
2452        dataOut.writeInt ( immediate() );
2453        dataOut.writeInt ( immediate() + switchArray().length - 1 );
2454
2455        /* write out the jump table */
2456        for (int aIndex=0; aIndex < switchArray().length; aIndex++)
2457        dataOut.writeInt (switchArray()[aIndex].offset);
2458
2459        size += 12 + switchArray().length * 4;
2460        break;
2461    }
2462        
2463    case OP_LOOKUPSWITCH: {
2464        dataOut.writeByte( opCode() );
2465        size = 1;
2466
2467        /* skip the zero-padded bytes that establish 4-byte
2468         * allignment of following data */

2469        for (int pIndex = index+1; (pIndex % 4) != 0; pIndex++) {
2470        dataOut.writeByte(0); /* zero these locations */
2471        size++;
2472        }
2473
2474        /*
2475         * Write out the default relative (default) jump addr, and the
2476         * number of match-offset pairs.
2477         */

2478        dataOut.writeInt ( branchTarget().offset );
2479        dataOut.writeInt ( switchArray().length );
2480
2481        for (int kIndex=0; kIndex<switchArray().length; kIndex++) {
2482        dataOut.writeInt ( switchArray()[kIndex].key );
2483        dataOut.writeInt ( switchArray()[kIndex].offset );
2484        }
2485        
2486        size += 8 + switchArray().length * 8;
2487        break;
2488    }
2489
2490    case OP_LDC:
2491    case OP_LDC_W:
2492    case OP_LDC2_W:
2493    case OP_BIPUSH:
2494    case OP_SIPUSH:
2495    case OP_ILOAD_0:
2496    case OP_ILOAD_1:
2497    case OP_ILOAD_2:
2498    case OP_ILOAD_3:
2499    case OP_FLOAD_0:
2500    case OP_FLOAD_1:
2501    case OP_FLOAD_2:
2502    case OP_FLOAD_3:
2503    case OP_LLOAD_0:
2504    case OP_LLOAD_1:
2505    case OP_LLOAD_2:
2506    case OP_LLOAD_3:
2507    case OP_DLOAD_0:
2508    case OP_DLOAD_1:
2509    case OP_DLOAD_2:
2510    case OP_DLOAD_3:
2511    case OP_ALOAD_0:
2512    case OP_ALOAD_1:
2513    case OP_ALOAD_2:
2514    case OP_ALOAD_3:
2515    case OP_ISTORE_0:
2516    case OP_ISTORE_1:
2517    case OP_ISTORE_2:
2518    case OP_ISTORE_3:
2519    case OP_FSTORE_0:
2520    case OP_FSTORE_1:
2521    case OP_FSTORE_2:
2522    case OP_FSTORE_3:
2523    case OP_LSTORE_0:
2524    case OP_LSTORE_1:
2525    case OP_LSTORE_2:
2526    case OP_LSTORE_3:
2527    case OP_DSTORE_0:
2528    case OP_DSTORE_1:
2529    case OP_DSTORE_2:
2530    case OP_DSTORE_3:
2531    case OP_ASTORE_0:
2532    case OP_ASTORE_1:
2533    case OP_ASTORE_2:
2534    case OP_ASTORE_3:
2535        {
2536        int op = opCode();
2537        throw new RuntimeException JavaDoc ("bad opcode for writing " + op);
2538        }
2539        
2540
2541    case OP_ILOAD:
2542        size = generate_loadstore (dataOut, OP_ILOAD_0);
2543        break;
2544
2545    case OP_FLOAD:
2546        size = generate_loadstore (dataOut, OP_FLOAD_0);
2547        break;
2548
2549    case OP_LLOAD:
2550        size = generate_loadstore (dataOut, OP_LLOAD_0);
2551        break;
2552
2553    case OP_DLOAD:
2554        size = generate_loadstore (dataOut, OP_DLOAD_0);
2555        break;
2556
2557    case OP_ALOAD:
2558        size = generate_loadstore (dataOut, OP_ALOAD_0);
2559        break;
2560
2561    case OP_ISTORE:
2562        size = generate_loadstore (dataOut, OP_ISTORE_0);
2563        break;
2564    case OP_FSTORE:
2565        size = generate_loadstore (dataOut, OP_FSTORE_0);
2566        break;
2567    case OP_LSTORE:
2568        size = generate_loadstore (dataOut, OP_LSTORE_0);
2569        break;
2570    case OP_DSTORE:
2571        size = generate_loadstore (dataOut, OP_DSTORE_0);
2572        break;
2573    case OP_ASTORE:
2574        size = generate_loadstore (dataOut, OP_ASTORE_0);
2575        break;
2576
2577    case OP_IINC:
2578        if (lvtIndex() <= 255
2579        && Byte.MIN_VALUE <= immediate()
2580        && immediate() <= Byte.MAX_VALUE ) {
2581        dataOut.writeByte( opCode() );
2582        dataOut.writeByte( lvtIndex() );
2583        dataOut.writeByte( immediate() );
2584        size = 3;
2585        } else {
2586        dataOut.writeByte ( OP_WIDE );
2587        dataOut.writeByte( opCode() );
2588        dataOut.writeShort( lvtIndex() );
2589        dataOut.writeShort( immediate() );
2590        size = 6;
2591        }
2592        break;
2593
2594    
2595    case AOP_IPUSH:
2596        dataOut.writeByte( realOpCode() );
2597        switch (realOpCode()) {
2598        case OP_ICONST_M1:
2599        case OP_ICONST_0:
2600        case OP_ICONST_1:
2601        case OP_ICONST_2:
2602        case OP_ICONST_3:
2603        case OP_ICONST_4:
2604        case OP_ICONST_5:
2605        size = 1;
2606        break;
2607        case OP_BIPUSH:
2608        size = 2;
2609        dataOut.writeByte( immediate() );
2610        break;
2611        case OP_SIPUSH:
2612        size = 3;
2613        dataOut.writeShort( immediate() );
2614        break;
2615        case OP_LDC:
2616        dataOut.writeByte( cpItemIndex() );
2617        size = 2;
2618        break;
2619        case OP_LDC_W:
2620        dataOut.writeShort( cpItemIndex() );
2621        size = 3;
2622        break;
2623        default:
2624        {
2625            int op = realOpCode();
2626            throw new RuntimeException JavaDoc ("no hint for AOP_IPUSH " + op);
2627        }
2628        }
2629        break;
2630
2631
2632    case AOP_FPUSH:
2633        dataOut.writeByte( realOpCode() );
2634        switch (realOpCode()) {
2635        case OP_FCONST_0:
2636        case OP_FCONST_1:
2637        case OP_FCONST_2:
2638        size = 1;
2639        break;
2640        case OP_LDC:
2641        dataOut.writeByte( cpItemIndex() );
2642        size = 2;
2643        break;
2644        case OP_LDC_W:
2645        dataOut.writeShort( cpItemIndex() );
2646        size = 3;
2647        break;
2648        default:
2649        throw new RuntimeException JavaDoc ("no hint for AOP_FPUSH");
2650        }
2651        break;
2652
2653
2654    case AOP_DPUSH:
2655        dataOut.writeByte( realOpCode() );
2656        switch (realOpCode()) {
2657        case OP_DCONST_0:
2658        case OP_DCONST_1:
2659        size = 1;
2660        break;
2661        case OP_LDC2_W:
2662        size = 3;
2663        dataOut.writeShort( cpItemIndex() );
2664        break;
2665        default:
2666        throw new RuntimeException JavaDoc ("no hint for AOP_DPUSH");
2667        }
2668        break;
2669
2670
2671    case AOP_LPUSH:
2672        dataOut.writeByte( realOpCode() );
2673        switch (realOpCode()) {
2674        case OP_LCONST_0:
2675        case OP_LCONST_1:
2676        size = 1;
2677        break;
2678        case OP_LDC2_W:
2679        size = 3;
2680        dataOut.writeShort( cpItemIndex() );
2681        break;
2682        default:
2683        throw new RuntimeException JavaDoc ("no hint for AOP_LPUSH");
2684        }
2685        break;
2686
2687    case AOP_SPUSH:
2688        dataOut.writeByte( realOpCode() );
2689        switch (realOpCode()) {
2690        case OP_LDC:
2691        dataOut.writeByte( cpItemIndex() );
2692        size = 2;
2693        break;
2694        case OP_LDC_W:
2695        dataOut.writeShort( cpItemIndex() );
2696        size = 3;
2697        break;
2698        default:
2699        throw new RuntimeException JavaDoc ("no hint for AOP_SPUSH");
2700        }
2701        break;
2702
2703    case AOP_COMMENT:
2704    case AOP_EXCMARKER:
2705
2706        return 0;
2707
2708    default:
2709        {
2710        int bad = opCode();
2711        throw new RuntimeException JavaDoc ("bad opcode " + bad);
2712        }
2713    }
2714    if (size == 0) {
2715        int bad = opCode();
2716        throw new RuntimeException JavaDoc ("size not set " + bad);
2717    }
2718    return(size);
2719    } // writeFile
2720

2721
2722    
2723    /* some functions to do sign extension / unextension */
2724
2725    public static long unextend32 (long i) {
2726    if (i < 0)
2727        i += 0x100000000l;
2728    return i;
2729    }
2730
2731    public static int unextend16 (int i) {
2732    if (i < 0)
2733        i += 0x10000;
2734    return i;
2735    }
2736
2737    public static int unextend8 (int i) {
2738    if (i < 0)
2739        i += 0x100;
2740    return i;
2741    }
2742
2743    public static int extend8 (int i) {
2744    if (i > 0x7F)
2745        i -= 0x100;
2746    return i;
2747    }
2748
2749    public static int extend16 (int i) {
2750    if (i > 0x7FFF)
2751        i -= 0x10000;
2752    return i;
2753    }
2754
2755
2756    public boolean usesLocals() {
2757    switch( opCode() ) {
2758    case OP_ILOAD:
2759    case OP_FLOAD:
2760    case OP_ALOAD:
2761    case OP_LLOAD:
2762    case OP_DLOAD:
2763    case OP_RET:
2764    case OP_ISTORE:
2765    case OP_FSTORE:
2766    case OP_ASTORE:
2767    case OP_LSTORE:
2768    case OP_DSTORE:
2769    case OP_IINC:
2770        return true;
2771    default:
2772        return false;
2773    }
2774    }
2775
2776    public Type localType()
2777    {
2778    switch( opCode() ) {
2779    case OP_RET:
2780        return Type.RETADDR;
2781    case OP_FSTORE:
2782    case OP_FLOAD:
2783        return Type.FLOAT;
2784    case OP_ASTORE:
2785    case OP_ALOAD:
2786        return Type.OBJECT;
2787    case OP_LSTORE:
2788    case OP_LLOAD:
2789        return Type.LONG;
2790    case OP_DSTORE:
2791    case OP_DLOAD:
2792        return Type.DOUBLE;
2793    case OP_ISTORE:
2794    case OP_ILOAD:
2795    case OP_IINC:
2796        return Type.INT;
2797    default:
2798        return null;
2799    }
2800    }
2801
2802    public boolean isStore() {
2803    switch( opCode() ) {
2804    case OP_ISTORE:
2805    case OP_FSTORE:
2806    case OP_ASTORE:
2807    case OP_LSTORE:
2808    case OP_DSTORE:
2809    case OP_IINC:
2810        return true;
2811    default:
2812        return false;
2813    }
2814    }
2815
2816    public boolean isLoad() {
2817    switch( opCode() ) {
2818    case OP_ILOAD:
2819    case OP_FLOAD:
2820    case OP_ALOAD:
2821    case OP_LLOAD:
2822    case OP_DLOAD:
2823    case OP_IINC:
2824    case OP_RET:
2825        return true;
2826    default:
2827        return false;
2828    }
2829    }
2830
2831    public boolean usesMethod() {
2832    switch( opCode() ) {
2833    case OP_INVOKESPECIAL:
2834    case OP_INVOKEVIRTUAL:
2835    case OP_INVOKESTATIC:
2836    case OP_INVOKEINTERFACE:
2837        return true;
2838    default:
2839        return false;
2840    }
2841    }
2842
2843    public boolean usesField() {
2844    switch( opCode() ) {
2845    case OP_GETSTATIC:
2846    case OP_PUTSTATIC:
2847    case OP_GETFIELD:
2848    case OP_PUTFIELD:
2849        return true;
2850    default:
2851        return false;
2852    }
2853    }
2854
2855    public boolean usesClass() {
2856    switch( opCode() ) {
2857    case OP_NEW:
2858    case OP_ANEWARRAY:
2859    case OP_MULTIANEWARRAY:
2860    case OP_CHECKCAST:
2861    case OP_INSTANCEOF:
2862        return true;
2863    default:
2864        return false;
2865    }
2866    }
2867
2868
2869    boolean isLongjump() {
2870    return (realOpCode() == OP_GOTO_W || realOpCode() == OP_JSR_W);
2871    }
2872
2873    void setLongjump(boolean b) {
2874    switch(opCode()) {
2875    case OP_GOTO:
2876        setRealOpCode( b ? OP_GOTO_W : OP_GOTO );
2877        break;
2878    case OP_JSR:
2879        setRealOpCode( b ? OP_JSR_W : OP_JSR );
2880        break;
2881    case OP_IFEQ:
2882    case OP_IFNE:
2883    case OP_IFLT:
2884    case OP_IFGE:
2885    case OP_IFGT:
2886    case OP_IFLE:
2887    case OP_IF_ICMPEQ:
2888    case OP_IF_ICMPNE:
2889    case OP_IF_ICMPLT:
2890    case OP_IF_ICMPGE:
2891    case OP_IF_ICMPGT:
2892    case OP_IF_ICMPLE:
2893    case OP_IF_ACMPEQ:
2894    case OP_IF_ACMPNE:
2895    case OP_IFNULL:
2896    case OP_IFNONNULL:
2897    case OP_TABLESWITCH:
2898    case OP_LOOKUPSWITCH:
2899        if (b) throw new GlobalException
2900        ("attempt to call setLongJump on a branch type that does not support it");
2901    default:
2902        throw new GlobalException
2903        ("attempt to call setLongJump on a opcode that does not support it");
2904    }
2905    } // setLongjump
2906

2907    // return how many stack arguments this instruction takes
2908
public int countArgs () {
2909    switch( opCode() ) {
2910    case OP_IFEQ:
2911    case OP_IFNE:
2912    case OP_IFLT:
2913    case OP_IFGE:
2914    case OP_IFGT:
2915    case OP_IFLE:
2916    case OP_IFNULL:
2917    case OP_IFNONNULL:
2918    case OP_TABLESWITCH:
2919    case OP_LOOKUPSWITCH:
2920    case OP_IRETURN:
2921    case OP_LRETURN:
2922    case OP_FRETURN:
2923    case OP_DRETURN:
2924    case OP_ARETURN:
2925    case OP_ATHROW:
2926    case AOP_GOTOBLK:
2927    case OP_NEWARRAY:
2928    case OP_ANEWARRAY:
2929    case OP_CHECKCAST:
2930    case OP_INSTANCEOF:
2931    case OP_GETFIELD:
2932    case OP_PUTSTATIC:
2933        return 1;
2934
2935    case OP_IF_ICMPEQ:
2936    case OP_IF_ICMPNE:
2937    case OP_IF_ICMPLT:
2938    case OP_IF_ICMPGE:
2939    case OP_IF_ICMPGT:
2940    case OP_IF_ICMPLE:
2941    case OP_IF_ACMPEQ:
2942    case OP_IF_ACMPNE:
2943    case OP_PUTFIELD:
2944        return 2;
2945
2946    case OP_GOTO:
2947    case OP_RETURN:
2948    case OP_JSR:
2949    case OP_NEW:
2950    case AOP_IPUSH:
2951    case OP_GETSTATIC:
2952        return 0;
2953
2954    case OP_INVOKEVIRTUAL:
2955    case OP_INVOKESPECIAL:
2956    case OP_INVOKEINTERFACE:
2957        // descriptor.count() adds 1
2958
return descriptor().count();
2959
2960    case OP_INVOKESTATIC:
2961        return descriptor().count() - 1;
2962
2963    case AOP_LABEL:
2964        throw new IllegalStateException JavaDoc ("countArgs called for label");
2965
2966    default:
2967        throw new RuntimeException JavaDoc("unimplemented: " + recString());
2968    }
2969    }
2970
2971    public int countRets () {
2972    switch (opCode()) {
2973    case OP_IFEQ:
2974    case OP_IFNE:
2975    case OP_IFLT:
2976    case OP_IFGE:
2977    case OP_IFGT:
2978    case OP_IFLE:
2979    case OP_IFNULL:
2980    case OP_IFNONNULL:
2981    case OP_TABLESWITCH:
2982    case OP_LOOKUPSWITCH:
2983    case OP_IRETURN:
2984    case OP_LRETURN:
2985    case OP_FRETURN:
2986    case OP_DRETURN:
2987    case OP_ARETURN:
2988    case OP_RETURN:
2989    case OP_ATHROW:
2990    case AOP_GOTOBLK:
2991    case OP_IF_ICMPEQ:
2992    case OP_IF_ICMPNE:
2993    case OP_IF_ICMPLT:
2994    case OP_IF_ICMPGE:
2995    case OP_IF_ICMPGT:
2996    case OP_IF_ICMPLE:
2997    case OP_IF_ACMPEQ:
2998    case OP_IF_ACMPNE:
2999    case OP_GOTO:
3000    case OP_CHECKCAST:
3001    case OP_PUTSTATIC:
3002    case OP_PUTFIELD:
3003        return 0;
3004
3005    case OP_NEW:
3006    case OP_NEWARRAY:
3007    case OP_ANEWARRAY:
3008    case OP_MULTIANEWARRAY:
3009    case OP_JSR:
3010    case OP_INSTANCEOF:
3011    case AOP_IPUSH:
3012    case OP_ACONST_NULL:
3013        return 1;
3014
3015    case OP_INVOKEVIRTUAL:
3016    case OP_INVOKESPECIAL:
3017    case OP_INVOKESTATIC:
3018    case OP_INVOKEINTERFACE:
3019        return descriptor().ret.category();
3020
3021    case OP_GETFIELD:
3022    case OP_GETSTATIC:
3023        return type().category();
3024
3025    case AOP_LABEL:
3026        throw new IllegalStateException JavaDoc ("countRets called for label");
3027
3028    default:
3029        throw new RuntimeException JavaDoc("unimplemented: " + recString());
3030    }
3031    }
3032
3033    // return how many stack elements this instruction uses. XXXX - incomplete
3034

3035    public int stackUse() {
3036    return countArgs() - countRets();
3037    }
3038
3039    public boolean usesBranch() {
3040    switch( opCode() ) {
3041    case OP_IFEQ:
3042    case OP_IFNE:
3043    case OP_IFLT:
3044    case OP_IFGE:
3045    case OP_IFGT:
3046    case OP_IFLE:
3047    case OP_IF_ICMPEQ:
3048    case OP_IF_ICMPNE:
3049    case OP_IF_ICMPLT:
3050    case OP_IF_ICMPGE:
3051    case OP_IF_ICMPGT:
3052    case OP_IF_ICMPLE:
3053    case OP_IF_ACMPEQ:
3054    case OP_IF_ACMPNE:
3055    case OP_JSR:
3056    case OP_IFNULL:
3057    case OP_IFNONNULL:
3058    case OP_GOTO:
3059    case OP_TABLESWITCH:
3060    case OP_LOOKUPSWITCH:
3061        return true;
3062    default:
3063        return false;
3064    }
3065    } // usesBranch
3066

3067    public boolean isReturn()
3068    {
3069    int op = opCode ();
3070    if (op == Instruction.OP_RETURN || op == Instruction.OP_IRETURN ||
3071        op == Instruction.OP_LRETURN || op == Instruction.OP_ARETURN ||
3072        op == Instruction.OP_FRETURN || op == Instruction.OP_DRETURN)
3073        return true;
3074    else
3075        return false;
3076    }
3077
3078    public boolean isSwitch() {
3079    return opCode() == OP_TABLESWITCH || opCode() == OP_LOOKUPSWITCH;
3080    }
3081
3082    /* Invert a conditional jump (ifeq becomes ifne, etc.) */
3083
3084    public static int invCondition (int op)
3085    {
3086    switch (op) {
3087    case Instruction.OP_IFNULL:
3088        return Instruction.OP_IFNONNULL;
3089    case Instruction.OP_IFNONNULL:
3090        return Instruction.OP_IFNULL;
3091    case Instruction.OP_IFEQ:
3092        return Instruction.OP_IFNE;
3093    case Instruction.OP_IFNE:
3094        return Instruction.OP_IFEQ;
3095    case Instruction.OP_IFLE:
3096        return Instruction.OP_IFGT;
3097    case Instruction.OP_IFLT:
3098        return Instruction.OP_IFGE;
3099    case Instruction.OP_IFGT:
3100        return Instruction.OP_IFLE;
3101    case Instruction.OP_IFGE:
3102        return Instruction.OP_IFLT;
3103    case Instruction.OP_IF_ACMPEQ:
3104        return Instruction.OP_IF_ACMPNE;
3105    case Instruction.OP_IF_ACMPNE:
3106        return Instruction.OP_IF_ACMPEQ;
3107    case Instruction.OP_IF_ICMPEQ:
3108        return Instruction.OP_IF_ICMPNE;
3109    case Instruction.OP_IF_ICMPNE:
3110        return Instruction.OP_IF_ICMPEQ;
3111    case Instruction.OP_IF_ICMPLE:
3112        return Instruction.OP_IF_ICMPGT;
3113    case Instruction.OP_IF_ICMPLT:
3114        return Instruction.OP_IF_ICMPGE;
3115    case Instruction.OP_IF_ICMPGT:
3116        return Instruction.OP_IF_ICMPLE;
3117    case Instruction.OP_IF_ICMPGE:
3118        return Instruction.OP_IF_ICMPLT;
3119
3120    default:
3121        throw new IllegalStateException JavaDoc ("Not a conditional jump: " + op);
3122    }
3123    }
3124
3125    /**
3126     * if this refers to a local variable its index will be
3127     * increased by delta.
3128     * @param delta increment for index
3129     * @return a reference to this
3130     */

3131    Instruction advanceLocals (int delta) {
3132    if ( usesLocals() )
3133        setLvtIndex( lvtIndex() + delta );
3134    return this;
3135    }
3136
3137
3138    // for newarray
3139
public static final int NAT_BOOLEAN = 4;
3140    public static final int NAT_CHAR = 5;
3141    public static final int NAT_FLOAT = 6;
3142    public static final int NAT_DOUBLE = 7;
3143    public static final int NAT_BYTE = 8;
3144    public static final int NAT_SHORT = 9;
3145    public static final int NAT_INT = 10;
3146    public static final int NAT_LONG = 11;
3147
3148    public static final int OP_NOP = 0;
3149    public static final int OP_MONITORENTER = 194;
3150    public static final int OP_MONITOREXIT = 195;
3151    public static final int OP_WIDE = 196;
3152    public static final int OP_NEW = 187;
3153    public static final int OP_NEWARRAY = 188;
3154    public static final int OP_ANEWARRAY = 189;
3155    public static final int OP_MULTIANEWARRAY = 197;
3156    public static final int OP_RET = 169;
3157    public static final int OP_IRETURN = 172;
3158    public static final int OP_LRETURN = 173;
3159    public static final int OP_FRETURN = 174;
3160    public static final int OP_DRETURN = 175;
3161    public static final int OP_ARETURN = 176;
3162    public static final int OP_RETURN = 177;
3163    public static final int OP_CHECKCAST = 192;
3164    public static final int OP_INSTANCEOF = 193;
3165    public static final int OP_INVOKEVIRTUAL = 182;
3166    public static final int OP_INVOKESPECIAL = 183;
3167    public static final int OP_INVOKESTATIC = 184;
3168    public static final int OP_INVOKEINTERFACE = 185;
3169    public static final int OP_IFEQ = 153;
3170    public static final int OP_IFNE = 154;
3171    public static final int OP_IFLT = 155;
3172    public static final int OP_IFGE = 156;
3173    public static final int OP_IFGT = 157;
3174    public static final int OP_IFLE = 158;
3175    public static final int OP_IF_ICMPEQ = 159;
3176    public static final int OP_IF_ICMPNE = 160;
3177    public static final int OP_IF_ICMPLT = 161;
3178    public static final int OP_IF_ICMPGE = 162;
3179    public static final int OP_IF_ICMPGT = 163;
3180    public static final int OP_IF_ICMPLE = 164;
3181    public static final int OP_IF_ACMPEQ = 165;
3182    public static final int OP_IF_ACMPNE = 166;
3183    public static final int OP_GOTO = 167;
3184    public static final int OP_GOTO_W = 200;
3185    public static final int OP_JSR = 168;
3186    public static final int OP_TABLESWITCH = 170;
3187    public static final int OP_LOOKUPSWITCH = 171;
3188    public static final int OP_IFNULL = 198;
3189    public static final int OP_IFNONNULL = 199;
3190    public static final int OP_JSR_W = 201;
3191    public static final int OP_ATHROW = 191;
3192    public static final int OP_ACONST_NULL = 1;
3193    public static final int OP_ICONST_M1 = 2;
3194    public static final int OP_ICONST_0 = 3;
3195    public static final int OP_ICONST_1 = 4;
3196    public static final int OP_ICONST_2 = 5;
3197    public static final int OP_ICONST_3 = 6;
3198    public static final int OP_ICONST_4 = 7;
3199    public static final int OP_ICONST_5 = 8;
3200    public static final int OP_LCONST_0 = 9;
3201    public static final int OP_LCONST_1 = 10;
3202    public static final int OP_FCONST_0 = 11;
3203    public static final int OP_FCONST_1 = 12;
3204    public static final int OP_FCONST_2 = 13;
3205    public static final int OP_DCONST_0 = 14;
3206    public static final int OP_DCONST_1 = 15;
3207    public static final int OP_LDC = 18;
3208    public static final int OP_LDC_W = 19;
3209    public static final int OP_LDC2_W = 20;
3210    public static final int OP_BIPUSH = 16;
3211    public static final int OP_SIPUSH = 17;
3212    public static final int OP_POP = 87;
3213    public static final int OP_POP2 = 88;
3214    public static final int OP_ILOAD = 21;
3215    public static final int OP_ILOAD_0 = 26;
3216    public static final int OP_ILOAD_1 = 27;
3217    public static final int OP_ILOAD_2 = 28;
3218    public static final int OP_ILOAD_3 = 29;
3219    public static final int OP_FLOAD = 23;
3220    public static final int OP_FLOAD_0 = 34;
3221    public static final int OP_FLOAD_1 = 35;
3222    public static final int OP_FLOAD_2 = 36;
3223    public static final int OP_FLOAD_3 = 37;
3224    public static final int OP_LLOAD = 22;
3225    public static final int OP_LLOAD_0 = 30;
3226    public static final int OP_LLOAD_1 = 31;
3227    public static final int OP_LLOAD_2 = 32;
3228    public static final int OP_LLOAD_3 = 33;
3229    public static final int OP_DLOAD = 24;
3230    public static final int OP_DLOAD_0 = 38;
3231    public static final int OP_DLOAD_1 = 39;
3232    public static final int OP_DLOAD_2 = 40;
3233    public static final int OP_DLOAD_3 = 41;
3234    public static final int OP_ALOAD = 25;
3235    public static final int OP_ALOAD_0 = 42;
3236    public static final int OP_ALOAD_1 = 43;
3237    public static final int OP_ALOAD_2 = 44;
3238    public static final int OP_ALOAD_3 = 45;
3239    public static final int OP_ISTORE = 54;
3240    public static final int OP_ISTORE_0 = 59;
3241    public static final int OP_ISTORE_1 = 60;
3242    public static final int OP_ISTORE_2 = 61;
3243    public static final int OP_ISTORE_3 = 62;
3244    public static final int OP_FSTORE = 56;
3245    public static final int OP_FSTORE_0 = 67;
3246    public static final int OP_FSTORE_1 = 68;
3247    public static final int OP_FSTORE_2 = 69;
3248    public static final int OP_FSTORE_3 = 70;
3249    public static final int OP_LSTORE = 55;
3250    public static final int OP_LSTORE_0 = 63;
3251    public static final int OP_LSTORE_1 = 64;
3252    public static final int OP_LSTORE_2 = 65;
3253    public static final int OP_LSTORE_3 = 66;
3254    public static final int OP_DSTORE = 57;
3255    public static final int OP_DSTORE_0 = 71;
3256    public static final int OP_DSTORE_1 = 72;
3257    public static final int OP_DSTORE_2 = 73;
3258    public static final int OP_DSTORE_3 = 74;
3259    public static final int OP_ASTORE = 58;
3260    public static final int OP_ASTORE_0 = 75;
3261    public static final int OP_ASTORE_1 = 76;
3262    public static final int OP_ASTORE_2 = 77;
3263    public static final int OP_ASTORE_3 = 78;
3264    public static final int OP_GETSTATIC = 178;
3265    public static final int OP_PUTSTATIC = 179;
3266    public static final int OP_GETFIELD = 180;
3267    public static final int OP_PUTFIELD = 181;
3268    public static final int OP_DUP = 89;
3269    public static final int OP_DUP_X1 = 90;
3270    public static final int OP_DUP_X2 = 91;
3271    public static final int OP_DUP2 = 92;
3272    public static final int OP_DUP2_X1 = 93;
3273    public static final int OP_DUP2_X2 = 94;
3274    public static final int OP_SWAP = 95;
3275    public static final int OP_IADD = 96;
3276    public static final int OP_LADD = 97;
3277    public static final int OP_FADD = 98;
3278    public static final int OP_DADD = 99;
3279    public static final int OP_ISUB = 100;
3280    public static final int OP_LSUB = 101;
3281    public static final int OP_FSUB = 102;
3282    public static final int OP_DSUB = 103;
3283    public static final int OP_IMUL = 104;
3284    public static final int OP_LMUL = 105;
3285    public static final int OP_FMUL = 106;
3286    public static final int OP_DMUL = 107;
3287    public static final int OP_IDIV = 108;
3288    public static final int OP_LDIV = 109;
3289    public static final int OP_FDIV = 110;
3290    public static final int OP_DDIV = 111;
3291    public static final int OP_IREM = 112;
3292    public static final int OP_LREM = 113;
3293    public static final int OP_FREM = 114;
3294    public static final int OP_DREM = 115;
3295    public static final int OP_INEG = 116;
3296    public static final int OP_LNEG = 117;
3297    public static final int OP_FNEG = 118;
3298    public static final int OP_DNEG = 119;
3299    public static final int OP_ISHL = 120;
3300    public static final int OP_LSHL = 121;
3301    public static final int OP_ISHR = 122;
3302    public static final int OP_LSHR = 123;
3303    public static final int OP_IUSHR = 124;
3304    public static final int OP_LUSHR = 125;
3305    public static final int OP_IAND = 126;
3306    public static final int OP_LAND = 127;
3307    public static final int OP_IOR = 128;
3308    public static final int OP_LOR = 129;
3309    public static final int OP_IXOR = 130;
3310    public static final int OP_LXOR = 131;
3311    public static final int OP_IINC = 132;
3312    public static final int OP_LCMP = 148;
3313    public static final int OP_FCMPG = 149;
3314    public static final int OP_FCMPL = 150;
3315    public static final int OP_DCMPG = 151;
3316    public static final int OP_DCMPL = 152;
3317    public static final int OP_I2B = 145;
3318    public static final int OP_I2C = 146;
3319    public static final int OP_I2S = 147;
3320    public static final int OP_I2L = 133;
3321    public static final int OP_I2F = 134;
3322    public static final int OP_I2D = 135;
3323    public static final int OP_L2I = 136;
3324    public static final int OP_L2F = 137;
3325    public static final int OP_L2D = 138;
3326    public static final int OP_F2I = 139;
3327    public static final int OP_F2L = 140;
3328    public static final int OP_F2D = 141;
3329    public static final int OP_D2I = 142;
3330    public static final int OP_D2L = 143;
3331    public static final int OP_D2F = 144;
3332    public static final int OP_IALOAD = 46;
3333    public static final int OP_LALOAD = 47;
3334    public static final int OP_FALOAD = 48;
3335    public static final int OP_DALOAD = 49;
3336    public static final int OP_AALOAD = 50;
3337    public static final int OP_BALOAD = 51;
3338    public static final int OP_CALOAD = 52;
3339    public static final int OP_SALOAD = 53;
3340    public static final int OP_IASTORE = 79;
3341    public static final int OP_LASTORE = 80;
3342    public static final int OP_FASTORE = 81;
3343    public static final int OP_DASTORE = 82;
3344    public static final int OP_AASTORE = 83;
3345    public static final int OP_BASTORE = 84;
3346    public static final int OP_CASTORE = 85;
3347    public static final int OP_SASTORE = 86;
3348    public static final int OP_ARRAYLENGTH = 190;
3349
3350
3351    /* fake opcodes for generalized constant pushes and other things */
3352
3353    public static final int AOP_IPUSH = 0x100;
3354    public static final int AOP_FPUSH = 0x101;
3355    public static final int AOP_LPUSH = 0x102;
3356    public static final int AOP_DPUSH = 0x103;
3357    public static final int AOP_SPUSH = 0x104;
3358
3359    public static final int AOP_NONE = 0x200;
3360    public static final int AOP_EXCMARKER = 0x201;
3361    public static final int AOP_COMMENT = 0x202;
3362    public static final int AOP_GOTOBLK = 0x203;
3363    public static final int AOP_LABEL = 0x204;
3364    public static final int AOP_INVOKEINIT = 0x205;
3365
3366    public static final int AOP_GOTOTEMP = 0x206;
3367    
3368    /* Snippit assumes it can use opcodes >= to this */
3369    public static final int AOP_FREE = 0x300;
3370
3371    static final String JavaDoc [] mnemonics = {
3372    "nop", "aconst_null", "iconst_m1", "iconst_0",
3373    "iconst_1", "iconst_2", "iconst_3", "iconst_4",
3374    "iconst_5", "lconst_0", "lconst_1", "fconst_0",
3375    "fconst_1", "fconst_2", "dconst_0", "dconst_1",
3376        "bipush", "sipush", "ldc", "ldc_w",
3377        "ldc2_w", "iload", "lload", "fload",
3378    "dload", "aload", "iload_0", "iload_1",
3379    "iload_2", "iload_3", "lload_0", "lload_1",
3380    "lload_2", "lload_3", "fload_0", "fload_1",
3381    "fload_2", "fload_3", "dload_0", "dload_1",
3382    "dload_2", "dload_3", "aload_0", "aload_1",
3383    "aload_2", "aload_3", "iaload", "laload",
3384        "faload", "daload", "aaload", "baload",
3385        "caload", "saload", "istore", "lstore",
3386        "fstore", "dstore", "astore", "istore_0",
3387    "istore_1", "istore_2", "istore_3", "lstore_0",
3388    "lstore_1", "lstore_2", "lstore_3", "fstore_0",
3389    "fstore_1", "fstore_2", "fstore_3", "dstore_0",
3390    "dstore_1", "dstore_2", "dstore_3", "astore_0",
3391    "astore_1", "astore_2", "astore_3", "iastore",
3392    "lastore", "fastore", "dastore", "aastore",
3393    "bastore", "castore", "sastore", "pop",
3394    "pop2", "dup", "dup_x1", "dup_x2",
3395    "dup2", "dup2_x1", "dup2_x2", "swap",
3396    "iadd", "ladd", "fadd", "dadd",
3397    "isub", "lsub", "fsub", "dsub",
3398    "imul", "lmul", "fmul", "dmul",
3399    "idiv", "ldiv", "fdiv", "ddiv",
3400    "irem", "lrem", "frem", "drem",
3401    "ineg", "lneg", "fneg", "dneg",
3402    "ishl", "lshl", "ishr", "lshr",
3403    "iushr", "lushr", "iand", "land",
3404    "ior", "lor", "ixor", "lxor",
3405    "iinc", "i2l", "i2f", "i2d",
3406    "l2i", "l2f", "l2d", "f2i",
3407    "f2l", "f2d", "d2i", "d2l",
3408    "d2f", "i2b", "i2c", "i2s",
3409    "lcmp", "fcmpl", "fcmpg", "dcmpl",
3410    "dcmpg", "ifeq", "ifne", "iflt",
3411    "ifge", "ifgt", "ifle", "if_icmpeq",
3412    "if_icmpne", "if_icmplt", "if_icmpge", "if_icmpgt",
3413    "if_icmple", "if_acmpeq", "if_acmpne", "goto",
3414    "jsr", "ret", "tableswitch", "lookupswitch",
3415    "ireturn", "lreturn", "freturn", "dreturn",
3416    "areturn", "return", "getstatic", "putstatic",
3417    "getfield", "putfield", "invokevirtual", "invokespecial",
3418    "invokestatic", "invokeinterface","xxxunusedxxx1", "new",
3419    "newarray", "anewarray", "arraylength", "athrow",
3420    "checkcast", "instanceof", "monitorenter", "monitorexit",
3421    "wide", "multianewarray", "ifnull", "ifnonnull",
3422    "goto_w", "jsr_w", "breakpoint" };
3423
3424    int preferablyRealOpCode() {
3425    return realOpCode() == -1 ? opCode() : realOpCode();
3426    }
3427
3428
3429    public String JavaDoc recString() {
3430    return recString(true);
3431    }
3432
3433    // if printbranch is false then we do not include any information
3434
// about the branch target. This is because there is about 50
3435
// different ways a branch target could be represented depening on
3436
// context, so the caller might want to do that himself.
3437
String JavaDoc recString(boolean printbranch) {
3438    int switchVal = preferablyRealOpCode();
3439    if (switchVal == OP_WIDE)
3440        switchVal = opCode();
3441
3442    switch ( switchVal ) {
3443    case OP_IFEQ:
3444    case OP_IFNE:
3445    case OP_IFLT:
3446    case OP_IFGE:
3447    case OP_IFGT:
3448    case OP_IFLE:
3449    case OP_IF_ICMPEQ:
3450    case OP_IF_ICMPNE:
3451    case OP_IF_ICMPLT:
3452    case OP_IF_ICMPGE:
3453    case OP_IF_ICMPGT:
3454    case OP_IF_ICMPLE:
3455    case OP_IF_ACMPEQ:
3456    case OP_IF_ACMPNE:
3457    case OP_JSR:
3458    case OP_JSR_W:
3459    case OP_IFNULL:
3460    case OP_IFNONNULL:
3461    case OP_GOTO:
3462    case OP_GOTO_W:
3463        if (!printbranch || branchTarget() == null)
3464        return mnemonics[preferablyRealOpCode()];
3465        if (branchTarget().instr != null)
3466        return mnemonics[preferablyRealOpCode()] + " " + branchTarget().instr.pc();
3467        else if (branchTarget().block != null)
3468        return mnemonics[preferablyRealOpCode()] + " #B" + branchTarget().block.swval;
3469        else
3470        return (mnemonics[preferablyRealOpCode()] + " _");
3471
3472    case OP_TABLESWITCH:
3473    case OP_LOOKUPSWITCH:
3474        {
3475        if (!printbranch || branchTarget() == null)
3476            return mnemonics[preferablyRealOpCode()];
3477
3478        StringBuffer JavaDoc s = new StringBuffer JavaDoc();
3479        BranchTarget[] swa = switchArray();
3480
3481        if (branchTarget().instr != null)
3482            s.append (mnemonics[preferablyRealOpCode()] + " " + branchTarget().instr.pc());
3483        else if (branchTarget().block != null)
3484            s.append (mnemonics[preferablyRealOpCode()] + " #B" + branchTarget().block.swval);
3485        else
3486            s.append (mnemonics[preferablyRealOpCode()] + " _");
3487        
3488        if (swa == null)
3489            return s.toString();
3490            
3491        for (int i = 0; i < swa.length; i++) {
3492            s.append (" ");
3493            s.append (immediate()+i);
3494            s.append (":");
3495            if(swa[i].instr != null)
3496            s.append(swa[i].instr.pc());
3497            else if (swa[i].block != null)
3498            s.append("#B" + swa[i].block.swval);
3499            else
3500            s.append("_");
3501        }
3502
3503        return s.toString();
3504        }
3505
3506    case OP_ISTORE:
3507    case OP_FSTORE:
3508    case OP_LSTORE:
3509    case OP_DSTORE:
3510    case OP_ASTORE:
3511    case OP_ILOAD:
3512    case OP_FLOAD:
3513    case OP_LLOAD:
3514    case OP_DLOAD:
3515    case OP_ALOAD:
3516    case OP_RET:
3517        return mnemonics[opCode()] + " " + lvtIndex();
3518
3519    case OP_IINC:
3520        return mnemonics[opCode()] + " " + immediate() + " " + lvtIndex();
3521
3522    case OP_GETSTATIC:
3523    case OP_PUTSTATIC:
3524    case OP_GETFIELD:
3525    case OP_PUTFIELD:
3526        return mnemonics[preferablyRealOpCode()] + " " + classRef() +
3527        " . " + elemName() + " : " + type();
3528
3529    case OP_INVOKESPECIAL:
3530    case OP_INVOKEVIRTUAL:
3531    case OP_INVOKESTATIC:
3532    case OP_INVOKEINTERFACE:
3533        return mnemonics[preferablyRealOpCode()] + " " + classRef() +
3534        " . " + elemName() + " : " + descriptor();
3535
3536    case OP_NEW:
3537    case OP_ANEWARRAY:
3538    case OP_CHECKCAST:
3539    case OP_INSTANCEOF:
3540        return mnemonics[preferablyRealOpCode()] + " " + classRef();
3541
3542    case OP_MULTIANEWARRAY:
3543        return mnemonics[preferablyRealOpCode()] + " " + classRef() + " " + immediate();
3544
3545    case OP_BIPUSH:
3546    case OP_SIPUSH:
3547        return mnemonics[preferablyRealOpCode()] + " " + immediate();
3548
3549
3550    case OP_LDC:
3551    case OP_LDC_W:
3552        switch( opCode() ) {
3553        case AOP_IPUSH:
3554        return mnemonics[preferablyRealOpCode()] + " " + immediate();
3555        case AOP_FPUSH:
3556        return mnemonics[preferablyRealOpCode()] + " " + immediate_f();
3557        case AOP_SPUSH:
3558        return mnemonics[preferablyRealOpCode()] + " \"" +
3559            Util.quoteString(immediate_s()) + "\"";
3560        default:
3561        throw new RuntimeException JavaDoc("unknown type of ldc");
3562        }
3563
3564    case OP_LDC2_W:
3565        switch( opCode() ) {
3566        case AOP_LPUSH:
3567        return mnemonics[preferablyRealOpCode()] + " " + immediate_l();
3568        case AOP_DPUSH:
3569        return mnemonics[preferablyRealOpCode()] + " " + immediate_f();
3570        default:
3571        throw new RuntimeException JavaDoc("unknown type of ldc2");
3572        }
3573
3574    case OP_NEWARRAY:
3575        return mnemonics[preferablyRealOpCode()] + " " + immediate();
3576
3577    case OP_NOP:
3578    case OP_MONITORENTER:
3579    case OP_MONITOREXIT:
3580    case OP_IRETURN:
3581    case OP_LRETURN:
3582    case OP_FRETURN:
3583    case OP_DRETURN:
3584    case OP_ARETURN:
3585    case OP_RETURN:
3586    case OP_ATHROW:
3587    case OP_ACONST_NULL:
3588    case OP_ICONST_M1:
3589    case OP_ICONST_0:
3590    case OP_ICONST_1:
3591    case OP_ICONST_2:
3592    case OP_ICONST_3:
3593    case OP_ICONST_4:
3594    case OP_ICONST_5:
3595    case OP_FCONST_0:
3596    case OP_FCONST_1:
3597    case OP_FCONST_2:
3598    case OP_LCONST_0:
3599    case OP_LCONST_1:
3600    case OP_DCONST_0:
3601    case OP_DCONST_1 :
3602    case OP_POP:
3603    case OP_POP2:
3604    case OP_ILOAD_0:
3605    case OP_ILOAD_1:
3606    case OP_ILOAD_2:
3607    case OP_ILOAD_3:
3608    case OP_FLOAD_0:
3609    case OP_FLOAD_1:
3610    case OP_FLOAD_2:
3611    case OP_FLOAD_3:
3612    case OP_LLOAD_0:
3613    case OP_LLOAD_1:
3614    case OP_LLOAD_2:
3615    case OP_LLOAD_3:
3616    case OP_DLOAD_0:
3617    case OP_DLOAD_1:
3618    case OP_DLOAD_2:
3619    case OP_DLOAD_3:
3620    case OP_ALOAD_0:
3621    case OP_ALOAD_1:
3622    case OP_ALOAD_2:
3623    case OP_ALOAD_3:
3624    case OP_ISTORE_0:
3625    case OP_ISTORE_1:
3626    case OP_ISTORE_2:
3627    case OP_ISTORE_3:
3628    case OP_FSTORE_0:
3629    case OP_FSTORE_1:
3630    case OP_FSTORE_2:
3631    case OP_FSTORE_3:
3632    case OP_LSTORE_0:
3633    case OP_LSTORE_1:
3634    case OP_LSTORE_2:
3635    case OP_LSTORE_3:
3636    case OP_DSTORE_0:
3637    case OP_DSTORE_1:
3638    case OP_DSTORE_2:
3639    case OP_DSTORE_3:
3640    case OP_ASTORE_0:
3641    case OP_ASTORE_1:
3642    case OP_ASTORE_2:
3643    case OP_ASTORE_3:
3644    case OP_DUP:
3645    case OP_DUP_X1:
3646    case OP_DUP_X2:
3647    case OP_DUP2:
3648    case OP_DUP2_X1:
3649    case OP_DUP2_X2:
3650    case OP_SWAP:
3651    case OP_IADD:
3652    case OP_LADD:
3653    case OP_FADD:
3654    case OP_DADD:
3655    case OP_ISUB:
3656    case OP_LSUB:
3657    case OP_FSUB:
3658    case OP_DSUB:
3659    case OP_IMUL:
3660    case OP_LMUL:
3661    case OP_FMUL:
3662    case OP_DMUL:
3663    case OP_IDIV:
3664    case OP_LDIV:
3665    case OP_FDIV:
3666    case OP_DDIV:
3667    case OP_IREM:
3668    case OP_LREM:
3669    case OP_FREM:
3670    case OP_DREM:
3671    case OP_INEG:
3672    case OP_LNEG:
3673    case OP_FNEG:
3674    case OP_DNEG:
3675    case OP_ISHL:
3676    case OP_LSHL:
3677    case OP_ISHR:
3678    case OP_LSHR:
3679    case OP_IUSHR:
3680    case OP_LUSHR:
3681    case OP_IAND:
3682    case OP_LAND:
3683    case OP_IOR:
3684    case OP_LOR:
3685    case OP_IXOR:
3686    case OP_LXOR:
3687    case OP_LCMP:
3688    case OP_FCMPG:
3689    case OP_FCMPL:
3690    case OP_DCMPG:
3691    case OP_DCMPL:
3692    case OP_I2B:
3693    case OP_I2C:
3694    case OP_I2D:
3695    case OP_L2I:
3696    case OP_L2F:
3697    case OP_L2D:
3698    case OP_F2I:
3699    case OP_F2L:
3700    case OP_F2D:
3701    case OP_D2I:
3702    case OP_D2L:
3703    case OP_D2F:
3704    case OP_I2F:
3705    case OP_I2L:
3706    case OP_I2S:
3707    case OP_IALOAD:
3708    case OP_LALOAD:
3709    case OP_FALOAD:
3710    case OP_DALOAD:
3711    case OP_AALOAD:
3712    case OP_CALOAD:
3713    case OP_SALOAD:
3714    case OP_BALOAD:
3715    case OP_IASTORE:
3716    case OP_LASTORE:
3717    case OP_FASTORE:
3718    case OP_DASTORE:
3719    case OP_AASTORE:
3720    case OP_BASTORE:
3721    case OP_CASTORE:
3722    case OP_SASTORE:
3723    case OP_ARRAYLENGTH:
3724        return mnemonics[preferablyRealOpCode()];
3725    case AOP_IPUSH:
3726        return "IPUSH " + immediate();
3727    case AOP_FPUSH:
3728        return "FPUSH " + immediate_f();
3729    case AOP_DPUSH:
3730        return "DPUSH " + immediate_f();
3731    case AOP_LPUSH:
3732        return "LPUSH " + immediate_l();
3733    case AOP_SPUSH:
3734        return "SPUSH \"" + immediate_s() + "\"";
3735    case AOP_EXCMARKER:
3736        switch (lvtIndex()) {
3737        case 0:
3738        return "ExcEnter (" + immediate() + ": " + elemName() + ") " +
3739            branchTarget().recString();
3740        case 1:
3741        return "ExcLeave (" + immediate() + ": " + elemName() + ")";
3742        case 2:
3743        return "ExcReset";
3744        }
3745
3746    case AOP_GOTOBLK:
3747        return "gotoblk";
3748
3749    case AOP_LABEL:
3750        return "label";
3751
3752    default:
3753        throw new RuntimeException JavaDoc("unknown opcode " + switchVal);
3754    } // switch
3755
} // recString
3756

3757    static int mnemonic2opcode(String JavaDoc str) throws RuntimeException JavaDoc {
3758    if (str.equalsIgnoreCase("ipush")) return AOP_IPUSH;
3759    if (str.equalsIgnoreCase("fpush")) return AOP_FPUSH;
3760    if (str.equalsIgnoreCase("dpush")) return AOP_DPUSH;
3761    if (str.equalsIgnoreCase("lpush")) return AOP_LPUSH;
3762    if (str.equalsIgnoreCase("spush")) return AOP_SPUSH;
3763    for (int i = 0; i < mnemonics.length; i++)
3764        if (str.equalsIgnoreCase(mnemonics[i]))
3765        return i;
3766    throw new RuntimeException JavaDoc("bad mnemonic: " + str);
3767    }
3768
3769    // a.equals(b) iff (eq a b)
3770
// oh yea. im gettin mah lisp on
3771

3772    /** support Cloneable
3773     * @return hash code for this object
3774     */

3775    public int hashCode() {
3776    return super.hashCode();
3777    }
3778
3779    /** support Cloneable
3780     * @return true if objects are EQ.
3781     */

3782    public boolean equals(Object JavaDoc o) {
3783    return this == o;
3784    }
3785
3786    /** How big can this instruction possibly be when written to disk?
3787     * Immediates or local numbers are considered
3788     * when determining the size (ie, aload 0 is size 1) .
3789     * @return size in bytes
3790    */

3791    public int maxsize () {
3792    switch (preferablyRealOpCode()) {
3793    case OP_NOP:
3794    case OP_MONITORENTER:
3795    case OP_MONITOREXIT:
3796    case OP_IRETURN:
3797    case OP_LRETURN:
3798    case OP_FRETURN:
3799    case OP_DRETURN:
3800    case OP_ARETURN:
3801    case OP_RETURN:
3802    case OP_ATHROW:
3803    case OP_ACONST_NULL:
3804    case OP_POP:
3805    case OP_POP2:
3806    case OP_DUP:
3807    case OP_DUP_X1:
3808    case OP_DUP_X2:
3809    case OP_DUP2:
3810    case OP_DUP2_X1:
3811    case OP_DUP2_X2:
3812    case OP_SWAP:
3813    case OP_IADD:
3814    case OP_LADD:
3815    case OP_FADD:
3816    case OP_DADD:
3817    case OP_ISUB:
3818    case OP_LSUB:
3819    case OP_FSUB:
3820    case OP_DSUB:
3821    case OP_IMUL:
3822    case OP_LMUL:
3823    case OP_FMUL:
3824    case OP_DMUL:
3825    case OP_IDIV:
3826    case OP_LDIV:
3827    case OP_FDIV:
3828    case OP_DDIV:
3829    case OP_IREM:
3830    case OP_LREM:
3831    case OP_FREM:
3832    case OP_DREM:
3833    case OP_INEG:
3834    case OP_LNEG:
3835    case OP_FNEG:
3836    case OP_DNEG:
3837    case OP_ISHL:
3838    case OP_LSHL:
3839    case OP_ISHR:
3840    case OP_LSHR:
3841    case OP_IUSHR:
3842    case OP_LUSHR:
3843    case OP_IAND:
3844    case OP_LAND:
3845    case OP_IOR:
3846    case OP_LOR:
3847    case OP_IXOR:
3848    case OP_LXOR:
3849    case OP_LCMP:
3850    case OP_FCMPG:
3851    case OP_FCMPL:
3852    case OP_DCMPG:
3853    case OP_DCMPL:
3854    case OP_I2B:
3855    case OP_I2C:
3856    case OP_I2D:
3857    case OP_L2I:
3858    case OP_L2F:
3859    case OP_L2D:
3860    case OP_F2I:
3861    case OP_F2L:
3862    case OP_F2D:
3863    case OP_D2I:
3864    case OP_D2L:
3865    case OP_D2F:
3866    case OP_I2F:
3867    case OP_I2L:
3868    case OP_I2S:
3869    case OP_IALOAD:
3870    case OP_LALOAD:
3871    case OP_FALOAD:
3872    case OP_DALOAD:
3873    case OP_AALOAD:
3874    case OP_CALOAD:
3875    case OP_SALOAD:
3876    case OP_BALOAD:
3877    case OP_IASTORE:
3878    case OP_LASTORE:
3879    case OP_FASTORE:
3880    case OP_DASTORE:
3881    case OP_AASTORE:
3882    case OP_BASTORE:
3883    case OP_CASTORE:
3884    case OP_SASTORE:
3885    case OP_ARRAYLENGTH:
3886    case OP_ICONST_M1:
3887    case OP_ICONST_0:
3888    case OP_ICONST_1:
3889    case OP_ICONST_2:
3890    case OP_ICONST_3:
3891    case OP_ICONST_4:
3892    case OP_ICONST_5:
3893    case OP_FCONST_0:
3894    case OP_FCONST_1:
3895    case OP_FCONST_2:
3896    case OP_LCONST_0:
3897    case OP_LCONST_1:
3898    case OP_DCONST_0:
3899        case OP_DCONST_1:
3900    case OP_ILOAD_0:
3901    case OP_ILOAD_1:
3902    case OP_ILOAD_2:
3903    case OP_ILOAD_3:
3904    case OP_FLOAD_0:
3905    case OP_FLOAD_1:
3906    case OP_FLOAD_2:
3907    case OP_FLOAD_3:
3908    case OP_LLOAD_0:
3909    case OP_LLOAD_1:
3910    case OP_LLOAD_2:
3911    case OP_LLOAD_3:
3912    case OP_DLOAD_0:
3913    case OP_DLOAD_1:
3914    case OP_DLOAD_2:
3915    case OP_DLOAD_3:
3916    case OP_ALOAD_0:
3917    case OP_ALOAD_1:
3918    case OP_ALOAD_2:
3919    case OP_ALOAD_3:
3920    case OP_ISTORE_0:
3921    case OP_ISTORE_1:
3922    case OP_ISTORE_2:
3923    case OP_ISTORE_3:
3924    case OP_FSTORE_0:
3925    case OP_FSTORE_1:
3926    case OP_FSTORE_2:
3927    case OP_FSTORE_3:
3928    case OP_LSTORE_0:
3929    case OP_LSTORE_1:
3930    case OP_LSTORE_2:
3931    case OP_LSTORE_3:
3932    case OP_DSTORE_0:
3933    case OP_DSTORE_1:
3934    case OP_DSTORE_2:
3935    case OP_DSTORE_3:
3936    case OP_ASTORE_0:
3937    case OP_ASTORE_1:
3938    case OP_ASTORE_2:
3939    case OP_ASTORE_3:
3940        return 1;
3941                
3942    case OP_NEWARRAY:
3943    case OP_RET:
3944        case OP_LDC:
3945    case OP_BIPUSH:
3946        return 2;
3947                
3948    case OP_NEW:
3949    case OP_ANEWARRAY:
3950    case OP_CHECKCAST:
3951    case OP_INSTANCEOF:
3952    case OP_INVOKESPECIAL:
3953    case OP_INVOKEVIRTUAL:
3954    case OP_INVOKESTATIC:
3955    case OP_IFEQ:
3956    case OP_IFNE:
3957    case OP_IFLT:
3958    case OP_IFGE:
3959    case OP_IFGT:
3960    case OP_IFLE:
3961    case OP_IF_ICMPEQ:
3962    case OP_IF_ICMPNE:
3963    case OP_IF_ICMPLT:
3964    case OP_IF_ICMPGE:
3965    case OP_IF_ICMPGT:
3966    case OP_IF_ICMPLE:
3967    case OP_IF_ACMPEQ:
3968    case OP_IF_ACMPNE:
3969    case OP_IFNULL:
3970    case OP_IFNONNULL:
3971    case OP_LDC_W:
3972    case OP_LDC2_W:
3973    case OP_SIPUSH:
3974    case OP_GETSTATIC:
3975    case OP_PUTSTATIC:
3976    case OP_GETFIELD:
3977    case OP_PUTFIELD:
3978    case AOP_SPUSH:
3979        return 3;
3980                
3981    case OP_MULTIANEWARRAY:
3982        return 4;
3983                                        
3984    case OP_INVOKEINTERFACE:
3985    case OP_GOTO_W:
3986    case OP_JSR_W:
3987    case OP_GOTO:
3988    case OP_JSR:
3989        return 5;
3990                
3991    case OP_TABLESWITCH:
3992        return 16 + switchArray().length * 4;
3993
3994    case OP_LOOKUPSWITCH:
3995        return 12 + switchArray().length * 8;
3996
3997    case OP_IINC:
3998        if (lvtIndex() <= 255
3999        && Byte.MIN_VALUE <= immediate()
4000        && immediate() <= Byte.MAX_VALUE)
4001        return 3;
4002        else
4003        return 6;
4004
4005    case OP_ILOAD:
4006    case OP_FLOAD:
4007    case OP_LLOAD:
4008    case OP_DLOAD:
4009    case OP_ALOAD:
4010    case OP_ISTORE:
4011    case OP_FSTORE:
4012    case OP_LSTORE:
4013    case OP_DSTORE:
4014    case OP_ASTORE:
4015        if (lvtIndex() <= 3)
4016        return 1;
4017        else if (lvtIndex() <= 255)
4018        return 2;
4019        else
4020        return 4;
4021
4022    case AOP_IPUSH:
4023        if (immediate() >= -1 && immediate() <= 5)
4024        return 1;
4025        else if (Byte.MIN_VALUE <= immediate()
4026             && immediate() <= Byte.MAX_VALUE)
4027        return 2;
4028        else
4029        return 3;
4030
4031    case AOP_FPUSH:
4032        if (immediate_f() == 2)
4033        return 1;
4034
4035    case AOP_DPUSH:
4036        if (immediate_f() == 0 || immediate_f() == 1)
4037        return 1;
4038        else
4039        return 3;
4040
4041    case AOP_LPUSH:
4042        if (immediate_l() == 0 || immediate_l() == 1)
4043        return 1;
4044        else
4045        return 3;
4046
4047    default:
4048        throw new IllegalStateException JavaDoc ("bad opcode for maxsize");
4049    } // switch
4050

4051    } // maxsize
4052

4053}
4054
4055    
4056
Popular Tags