KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > jas > InsnOperand


1                                 // This is not visible outside the
2
// package. It is used to
3
// handle the various types
4
// of operands used by Insns.
5
package jas;
6
7 import java.io.*;
8
9 abstract class InsnOperand
10 {
11   abstract void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
12     throws IOException, jasError;
13   abstract int size(ClassEnv e, CodeAttr code) throws jasError;
14   abstract void resolve(ClassEnv e);
15   void writePrefix(ClassEnv e, CodeAttr ce, DataOutputStream out)
16     throws IOException, jasError
17   { return; }
18 }
19
20                                 // Used to implement targets of Insns
21
class LabelOperand extends InsnOperand
22 {
23   Label target;
24   Insn source;
25   boolean wide;
26
27   LabelOperand(Label l, Insn source)
28   { target = l; this.source = source; this.wide = false; }
29   LabelOperand(Label l, Insn source, boolean wide)
30   { target = l; this.source = source; this.wide = wide; }
31   int size(ClassEnv ce, CodeAttr code) { if (wide) return 4; else return 2; }
32   void resolve(ClassEnv e) { return; }
33   void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
34     throws IOException, jasError
35   {
36     if (wide) { target.writeWideOffset(ce, source, out); }
37     else { target.writeOffset(ce, source, out); } }
38 }
39
40 class UnsignedByteOperand extends InsnOperand
41 {
42   int val;
43
44   UnsignedByteOperand(int n) { val = n; }
45   int size(ClassEnv ce, CodeAttr code) { return 1; }
46   void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
47     throws IOException, jasError
48   {
49     if (val >= 256)
50       throw
51         new jasError("Operand is too large (" +val+ ") for this instruction");
52     out.writeByte((byte)(0xff & val));
53   }
54   void resolve(ClassEnv e) { return; }
55 }
56
57                                 // This (conditionally) adds a wide
58
// prefix if the value is larger than
59
// 256
60
class UnsignedByteWideOperand extends InsnOperand
61   implements RuntimeConstants
62 {
63   int val;
64
65   UnsignedByteWideOperand(int n) { val = n; }
66   int size(ClassEnv ce, CodeAttr code)
67   {
68     if (val >= 256) return 3;
69     return 1;
70   }
71   void writePrefix(ClassEnv e, CodeAttr ce, DataOutputStream out)
72     throws IOException
73   {
74     if (val > 255)
75       out.writeByte((byte)(opc_wide));
76   }
77   void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
78     throws IOException
79   {
80     if (val > 255)
81       out.writeShort((short)(0xffff & val));
82     else
83       out.writeByte((byte)(val & 0xff));
84   }
85   void resolve(ClassEnv e) { return; }
86 }
87
88 class ByteOperand extends InsnOperand
89 {
90   int val;
91
92   ByteOperand(int n) { val = n; }
93   int size(ClassEnv ce, CodeAttr code) { return 1; }
94   void resolve(ClassEnv e) { return; }
95   void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
96     throws IOException
97   { out.writeByte((byte)val); }
98 }
99
100 class IntegerOperand extends InsnOperand
101 {
102   int val;
103
104   IntegerOperand(int n) { val = n; }
105   int size(ClassEnv ce, CodeAttr code) { return 4; }
106   void resolve(ClassEnv e) { return; }
107   void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
108     throws IOException
109   { out.writeInt(val); }
110 }
111
112 class ShortOperand extends InsnOperand
113 {
114   int offset;
115   ShortOperand(int n) { offset = n; }
116   void resolve(ClassEnv e) { return; }
117   int size(ClassEnv ce, CodeAttr code) { return 2; }
118   void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
119     throws IOException
120   { out.writeShort((short)offset); }
121 }
122
123 class CPOperand extends InsnOperand
124 {
125   CP cpe;
126   boolean wide;
127   int size(ClassEnv ce, CodeAttr code) { if (wide) return 2; else return 1; }
128   CPOperand(CP cpe) { this.cpe = cpe; wide = true; }
129   CPOperand(CP cpe, boolean wide)
130   { this.cpe = cpe; this.wide = wide; }
131   void resolve(ClassEnv e)
132   { e.addCPItem(cpe); }
133   void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
134     throws IOException, jasError
135   {
136     int idx = e.getCPIndex(cpe);
137     if (wide)
138       { out.writeShort((short) idx); }
139     else
140       {
141         if (idx > 255)
142           { throw new jasError("exceeded size for small cpidx" + cpe); }
143         out.writeByte((byte) (0xff & (idx)));
144       }
145   }
146 }
147
148                                 // these are unique enough that
149
// they need a separate handler for their
150
// args
151
class LdcOperand extends InsnOperand implements RuntimeConstants
152 {
153   CP cpe;
154   Insn source;
155   boolean wide;
156
157   int size(ClassEnv ce, CodeAttr code) throws jasError
158   {
159     if (wide)
160       { return 2; }
161     else
162       {
163                                 // Should we promote it?
164
int idx = ce.getCPIndex(cpe);
165         // LJH
166
// System.out.println("getting idx in size: " + idx);
167
if (idx > 255)
168           {
169             wide = true;
170             source.opc = opc_ldc_w;
171             return 2;
172           }
173         return 1;
174       }
175   }
176   LdcOperand(Insn s, CP cpe) { source = s; this.cpe = cpe; wide = true; }
177   LdcOperand(Insn s, CP cpe, boolean wide)
178   { source = s; this.cpe = cpe; this.wide = wide; }
179
180   void resolve(ClassEnv e)
181   { e.addCPItem(cpe);
182       if (cpe instanceof ClassCP){
183         e.setHighVersion(true);
184       }
185   }
186
187   void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
188     throws IOException, jasError
189   {
190     int idx = e.getCPIndex(cpe);
191     // LJH
192
// System.out.println("Writing " + idx + " which as a short is " +
193
// ((short) idx) + " and is " + wide);
194
if (wide)
195       { out.writeShort((short) idx); }
196     else
197       {
198         if (idx > 255)
199           { throw new jasError("exceeded size for small cpidx" + cpe); }
200         out.writeByte((byte) (0xff & (idx)));
201       }
202   }
203 }
204
205   
206 class InvokeinterfaceOperand extends InsnOperand
207 {
208   CP cpe;
209   int nargs;
210
211   InvokeinterfaceOperand(CP cpe, int nargs)
212   { this.cpe = cpe; this.nargs = nargs; }
213
214   int size(ClassEnv ce, CodeAttr code) { return 4; }
215
216   void resolve(ClassEnv e)
217   { e.addCPItem(cpe); }
218
219   void write (ClassEnv e, CodeAttr ce, DataOutputStream out)
220     throws IOException, jasError
221   {
222     out.writeShort(e.getCPIndex(cpe));
223     out.writeByte((byte) (0xff & nargs));
224     out.writeByte(0);
225   }
226 }
227
228 class IincOperand extends InsnOperand
229   implements RuntimeConstants
230 {
231   int vindex, constt;
232
233   IincOperand(int vindex, int constt)
234   { this.vindex = vindex; this.constt = constt; }
235
236   int size(ClassEnv ce, CodeAttr code)
237   {
238     if ((vindex > 255) ||
239         (constt > 127) ||
240         (constt < -128))
241       return 5;
242     else
243       return 2;
244   }
245   void resolve(ClassEnv e) { return; }
246   void writePrefix(ClassEnv e, CodeAttr ce, DataOutputStream out)
247     throws IOException
248   {
249     if ((vindex > 255) ||
250         (constt > 127) ||
251         (constt < -128))
252       out.writeByte((byte)opc_wide);
253   }
254   void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
255     throws IOException
256   {
257     if ((vindex > 255) ||
258         (constt > 127) ||
259         (constt < -128))
260       {
261         out.writeShort((short)(0xffff & vindex));
262         out.writeShort((short)(0xffff & constt));
263       }
264     else
265       {
266         out.writeByte((byte) (0xff & vindex));
267         out.writeByte((byte) (0xff & constt));
268       }
269   }
270 }
271
272 class MultiarrayOperand extends InsnOperand
273 {
274   CP cpe;
275   int sz;
276
277   MultiarrayOperand(CP cpe, int sz)
278   { this.cpe = cpe; this.sz = sz; }
279   void resolve(ClassEnv e) { e.addCPItem(cpe); }
280   int size(ClassEnv ce, CodeAttr code) { return 3; }
281   void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
282     throws IOException, jasError
283   {
284     out.writeShort(e.getCPIndex(cpe));
285     out.writeByte((byte)(0xff & sz));
286   }
287 }
288
289 class LookupswitchOperand extends InsnOperand
290 {
291   Label dflt;
292   Insn source;
293   int match[];
294   Label jmp[];
295
296   LookupswitchOperand(Insn s, Label def, int m[], Label j[])
297   { dflt = def; jmp = j; match = m; source = s; }
298
299   void resolve (ClassEnv e) { return; }
300   int size(ClassEnv ce, CodeAttr code) throws jasError
301   {
302     int sz = 8; // 4 + 4 + padding + jumptable
303
int source_pc = code.getPc(source);
304     if (((source_pc+1) % 4) != 0)
305       {
306                 // need padding
307
sz += (4 - ((source_pc+1) % 4));
308       }
309
310     if (jmp != null)
311       { sz += 8*(jmp.length); }
312     return sz;
313   }
314
315   void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
316     throws IOException, jasError
317   {
318     int pad;
319     int source_pc = ce.getPc(source);
320
321     if (((source_pc+1) % 4) != 0)
322       { // need padding
323
pad = (4 - ((source_pc+1) % 4));
324     for (int x=0; x<pad; x++) out.writeByte(0);
325       }
326
327                 // write offset to default
328
// as a 4 byte signed value
329
dflt.writeWideOffset(ce, source, out);
330     if (jmp == null)
331       { out.writeInt(0); }
332     else
333       {
334     out.writeInt(jmp.length);
335     for (int x=0; x<jmp.length; x++)
336       {
337         out.writeInt(match[x]);
338         jmp[x].writeWideOffset(ce, source, out);
339       }
340       }
341   }
342 }
343
344     
345 class TableswitchOperand extends InsnOperand
346 {
347   int min, max;
348   Label dflt;
349   Label jmp[];
350   Insn source;
351
352   TableswitchOperand(Insn s,int min, int max, Label def, Label j[])
353   {
354     this.min = min; this.max = max;
355     dflt = def; jmp = j; source = s;
356   }
357
358   void resolve(ClassEnv e) { return; }
359
360   int size(ClassEnv ce, CodeAttr code)
361     throws jasError
362                                 // the *real* reason for making it a
363
// method..
364
{
365     int sz = 12; // 4+4+4+jmptable+padding...
366
int source_pc = code.getPc(source);
367     if (((source_pc+1) % 4) != 0)
368       { // need padding
369
sz += (4 - ((source_pc+1) % 4));
370       }
371     if (jmp != null)
372       { sz += 4*(jmp.length); }
373     return sz;
374   }
375
376   void write(ClassEnv e, CodeAttr ce, DataOutputStream out)
377     throws IOException, jasError
378   {
379     int pad;
380     int source_pc = ce.getPc(source);
381
382     if (((source_pc+1) % 4) != 0)
383       { // need padding
384
pad = (4 - ((source_pc+1) % 4));
385         for (int x=0; x<pad; x++) out.writeByte(0);
386       }
387     dflt.writeWideOffset(ce, source, out);
388     out.writeInt(min);
389     out.writeInt(max);
390     int cnt = jmp.length;
391     for (int x=0; x<cnt; x++)
392       { jmp[x].writeWideOffset(ce, source, out); }
393   }
394 }
395
396
Popular Tags