KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jas > Insn


1 /**
2  * An Insn is a generic instruction that is added to a
3  * CodeAttr to build up the code for a method.
4  * @see CodeAttr
5  * @see RuntimeConstants
6  * @author $Author: fqian $
7  * @version $Revision: 1.1 $
8  */

9
10
11 package jas;
12
13 import java.io.*;
14 import java.util.*;
15
16
17 public class Insn implements RuntimeConstants
18 {
19   int opc;
20   InsnOperand operand;
21
22                                 // private constructor, for the
23
// "strange" opcodes
24
Insn() { return; }
25   /**
26    * Instructions with no arguments are built with
27    * this constructor.
28    */

29   public Insn(int opc)
30     throws jasError
31   {
32     if (opcLengths[opc] == 1)
33       { operand = null; this.opc = opc; return; }
34     throw new jasError
35       (opcNames[opc] + " cannot be used without more parameters");
36   }
37
38   /**
39    * Instructions that take a single numeric argument. These are
40    * opc_bipush,
41    * opc_sipush,
42    * opc_ret,
43    * opc_iload,
44    * opc_lload,
45    * opc_fload,
46    * opc_dload,
47    * opc_aload,
48    * opc_istore,
49    * opc_lstore,
50    * opc_fstore,
51    * opc_dstore,
52    * opc_astore,
53    * opc_newarray
54    *
55    * Note that an extra wide prefix is automatically added
56    * for the following instructions if the numeric argument
57    * is larger than 256. Also note that while the spec makes
58    * no mention of opc_ret as being a "wideable" opcode, thats
59    * how the VM is implemented.
60    *
61    * opc_ret:
62    * opc_iload:
63    * opc_lload:
64    * opc_fload:
65    * opc_dload:
66    * opc_aload:
67    * opc_istore:
68    * opc_lstore:
69    * opc_fstore:
70    * opc_dstore:
71    * opc_astore:
72    *
73    */

74
75   public Insn(int opc, int val)
76     throws jasError
77   {
78     this.opc = opc;
79     switch (opc)
80       {
81       case opc_bipush: operand = new ByteOperand(val); break;
82       case opc_sipush: operand = new ShortOperand(val); break;
83       case opc_newarray:
84         operand = new UnsignedByteOperand(val);
85         break;
86       case opc_ret:
87       case opc_iload:
88       case opc_lload:
89       case opc_fload:
90       case opc_dload:
91       case opc_aload:
92       case opc_istore:
93       case opc_lstore:
94       case opc_fstore:
95       case opc_dstore:
96       case opc_astore:
97         operand = new UnsignedByteWideOperand(val);
98         break;
99       default:
100         throw new jasError
101           (opcNames[opc] + " does not take a numeric argument");
102       }
103   }
104   /**
105    * Instructions that take a Label as an argument. These are
106    * opc_jsr,
107    * opc_goto,
108    * opc_if_acmpne,
109    * opc_if_acmpeq,
110    * opc_if_icmpge,
111    * opc_if_icmple,
112    * opc_if_icmpgt,
113    * opc_if_icmplt,
114    * opc_if_icmpne,
115    * opc_if_icmpeq,
116    * opc_ifge,
117    * opc_ifgt,
118    * opc_ifne,
119    * opc_ifle,
120    * opc_iflt,
121    * opc_ifeq,
122    * opc_ifnull,
123    * opc_ifnonnull,
124    * opc_goto_w,
125    * opc_jsr_w
126    */

127   public Insn(int opc, Label target)
128     throws jasError
129   {
130     this.opc = opc;
131     switch(opc)
132       {
133       case opc_jsr:
134       case opc_goto:
135       case opc_if_acmpne:
136       case opc_if_acmpeq:
137       case opc_if_icmpge:
138       case opc_if_icmple:
139       case opc_if_icmpgt:
140       case opc_if_icmplt:
141       case opc_if_icmpne:
142       case opc_if_icmpeq:
143       case opc_ifge:
144       case opc_ifgt:
145       case opc_ifne:
146       case opc_ifle:
147       case opc_iflt:
148       case opc_ifeq:
149       case opc_ifnull:
150       case opc_ifnonnull:
151         operand = new LabelOperand(target, this);
152         break;
153       case opc_goto_w:
154       case opc_jsr_w:
155         operand = new LabelOperand(target, this, true);
156         break;
157       default:
158         throw new jasError
159           (opcNames[opc] + " does not take a label as its argument");
160       }
161   }
162   /**
163    * This constructor is used for instructions that take a CP item
164    * as their argument. These are
165    * opc_anewarray,
166    * opc_ldc_w,
167    * opc_ldc2_w,
168    * opc_invokenonvirtual,
169    * opc_invokestatic,
170    * opc_invokevirtual,
171    * opc_new,
172    * opc_checkcast,
173    * opc_instanceof,
174    * opc_getstatic,
175    * opc_putstatic,
176    * opc_getfield,
177    * opc_putfield,
178    * opc_ldc
179    */

180   public Insn(int opc, CP arg)
181     throws jasError
182   {
183     this.opc = opc;
184     switch(opc)
185       {
186       case opc_anewarray:
187       case opc_invokenonvirtual:
188       case opc_invokestatic:
189       case opc_invokevirtual:
190       case opc_new:
191       case opc_checkcast:
192       case opc_instanceof:
193       case opc_getstatic:
194       case opc_putstatic:
195       case opc_getfield:
196       case opc_putfield:
197         operand = new CPOperand(arg);
198         break;
199       case opc_ldc2_w:
200       case opc_ldc_w:
201         //System.out.println("ldc_w: arg: "+arg);
202
operand = new LdcOperand(this, arg);
203         break;
204       case opc_ldc:
205         operand = new LdcOperand(this, arg, false);
206         break;
207       default:
208         throw new jasError
209           (opcNames[opc] + " does not take a CP item as an argument");
210       }
211   }
212
213                                 // This allows the Insn a chance to
214
// add things to the global env if
215
// necessary. The CPInsnOperands
216
// use this to add the CP to the
217
// classEnv
218
void resolve(ClassEnv e)
219   { if (operand != null) { operand.resolve(e); } }
220
221   void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
222     throws IOException, jasError
223   {
224     if (operand != null)
225       operand.writePrefix(e, ce, out);
226     out.writeByte((byte) opc);
227     if (operand != null)
228       operand.write(e, ce, out);
229   }
230   int size(ClassEnv e, CodeAttr ce)
231     throws jasError
232   {
233     if (operand == null) return 1;
234     return (1 + operand.size(e, ce));
235   }
236 }
237
Popular Tags