KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sun > jdo > api > persistence > enhancer > classfile > Insn


1 /*
2  * The contents of this file are subject to the terms
3  * of the Common Development and Distribution License
4  * (the License). You may not use this file except in
5  * compliance with the License.
6  *
7  * You can obtain a copy of the license at
8  * https://glassfish.dev.java.net/public/CDDLv1.0.html or
9  * glassfish/bootstrap/legal/CDDLv1.0.txt.
10  * See the License for the specific language governing
11  * permissions and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL
14  * Header Notice in each file and include the License file
15  * at glassfish/bootstrap/legal/CDDLv1.0.txt.
16  * If applicable, add the following below the CDDL Header,
17  * with the fields enclosed by brackets [] replaced by
18  * you own identifying information:
19  * "Portions Copyrighted [year] [name of copyright owner]"
20  *
21  * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
22  */

23
24
25 package com.sun.jdo.api.persistence.enhancer.classfile;
26
27 import java.io.PrintStream JavaDoc;
28
29 /**
30  * Insn is an abstract class which represents a java VM instruction in a
31  * sequence of instructions.
32  */

33
34 abstract public class Insn implements VMConstants {
35   /* An instruction with no pc defined yet */
36   final static int NO_OFFSET = -1;
37
38   /* A special magic opcode for branch target pseudo instructions */
39   final public static int opc_target = -1;
40
41   /* The opcode of this instruction */
42   private int insnOpcode;
43
44   /* The pc of this instruction within the containing code sequence */
45   private int insnOffset = NO_OFFSET;
46
47   /* The next instruction in the code sequence */
48   private Insn nextInsn = null;
49
50   /* The previous instruction in the code sequence */
51   private Insn prevInsn = null;
52
53   /* public accessors */
54
55   /**
56    * Returns the next instruction in the code sequence
57    */

58   public Insn next() {
59     return nextInsn;
60   }
61
62   /**
63    * Returns the previous instruction in the code sequence
64    */

65   public Insn prev() {
66     return prevInsn;
67   }
68
69   /**
70    * Removes the current instruction from it's embedding sequence.
71    */

72   //@olsen: added method
73
public void remove() {
74     if (nextInsn != null)
75       nextInsn.prevInsn = prevInsn;
76
77     if (prevInsn != null)
78       prevInsn.nextInsn = nextInsn;
79
80     prevInsn = null;
81     nextInsn = null;
82   }
83
84   /**
85    * Insert the single instruction in the code sequence after this
86    * instruction.
87    * Returns the inserted instruction.
88    */

89   public Insn setNext(Insn i) {
90     if (nextInsn != null)
91       nextInsn.prevInsn = i;
92
93     if (i != null) {
94       i.nextInsn = nextInsn;
95       i.prevInsn = this;
96     }
97     nextInsn = i;
98     return i;
99   }
100
101   /**
102    * Insert an instruction sequence in the code sequence after this
103    * instruction.
104    * Returns the final instruction.
105    */

106   public Insn insert(Insn i) {
107     if (i == null)
108       return this;
109
110     Insn theNextInsn = nextInsn;
111     nextInsn = i;
112     i.prevInsn = this;
113
114     while (i.nextInsn != null)
115       i = i.nextInsn;
116     i.nextInsn = theNextInsn;
117     if (theNextInsn != null)
118       theNextInsn.prevInsn = i;
119     return i;
120   }
121
122   /**
123    * Append an instruction sequence at the end of this instruction
124    * sequence.
125    * Returns the final instruction.
126    */

127   public Insn append(Insn i) {
128     Insn thisInsn = this;
129     while (thisInsn.nextInsn != null)
130       thisInsn = thisInsn.nextInsn;
131     return thisInsn.insert(i);
132   }
133
134   /**
135    * Return the opcode for this instruction
136    */

137   public int opcode() {
138     return insnOpcode;
139   }
140
141   /**
142    * Return the offset of this instruction in the containing code sequence
143    */

144   public int offset() {
145     return insnOffset;
146   }
147
148   /**
149    * How many words of stack operands does this instruction take?
150    */

151   abstract public int nStackArgs();
152
153   /**
154    * How many words of stack results does this instruction deposit?
155    */

156   abstract public int nStackResults();
157
158   /**
159    * What are the types of the stack operands ?
160    */

161   abstract public String JavaDoc argTypes();
162
163   /**
164    * What are the types of the stack results?
165    */

166   abstract public String JavaDoc resultTypes();
167
168   /**
169    * Does this instruction branch?
170    */

171   abstract public boolean branches();
172
173   /**
174    * Mark possible branch targets
175    */

176   public void markTargets() {
177   }
178
179   /**
180    * Return the name of the operation for a given opcode
181    */

182   public static String JavaDoc opName(int opcode) {
183     if (opcode == opc_target)
184         return "target:";//NOI18N
185
if (opcode >=0 && opcode <= VMOp.ops.length)
186       return VMOp.ops[opcode].name();
187     else
188         throw new InsnError("invalid opcode for opName: " + opcode);//NOI18N
189
}
190
191   /* Instruction creation interfaces - these should be used for all
192    * instructions except opc_iinc, opc_tableswitch, opc_lookupswitch,
193    * opc_multidimarraynew, and opc_invokeinterface.
194    */

195
196   /**
197    * Create an instruction which requires no immediate operands
198    */

199   public static Insn create(int theOpCode) {
200     return new InsnSingle(theOpCode);
201   }
202
203   /**
204    * Create an instruction which requires a single constant from the
205    * constant pool as an immediate operand.
206    */

207   public static Insn create(int theOpCode, ConstBasic constValue) {
208     return new InsnConstOp(theOpCode, constValue);
209   }
210
211   /**
212    * Create an instruction which requires a single integral constant
213    * as an immediate operand.
214    */

215   public static Insn create(int theOpCode, int intValue) {
216     return new InsnIntOp(theOpCode, intValue);
217   }
218
219   /**
220    * Create an instruction which requires a single branch offset
221    * as an immediate operand.
222    */

223   public static Insn create(int theOpCode, InsnTarget target) {
224     return new InsnTargetOp(theOpCode, target);
225   }
226
227   /**
228    * Print the sequence of instructions to the output stream
229    */

230   public void printList(PrintStream JavaDoc out) {
231     Insn insn = this;
232     while (insn != null) {
233       insn.print(out, 0);
234       insn = insn.next();
235     }
236   }
237
238   /**
239    * Print this instruction to the output stream
240    */

241   public void printInsn(PrintStream JavaDoc out) {
242     print(out, 0);
243   }
244
245   /* package local methods */
246
247   abstract void print (PrintStream JavaDoc out, int indent);
248
249   abstract int store(byte[] buf, int index);
250
251   /* return the size of the instruction in bytes
252    * Note: some instructions are unable to answer correctly until their
253    * start offset is known
254    */

255   abstract int size();
256
257   /* Set the offset of the instruction and return the offset of the
258      following instruction */

259
260   final int resolveOffset(int pc) {
261     insnOffset = pc;
262     return pc + size();
263   }
264
265   Insn(int theOpcode, int theOffset) {
266     insnOpcode = theOpcode;
267     insnOffset = theOffset;
268   }
269
270   static int storeInt(byte buf[], int index, int v) {
271     buf[index++] = (byte) (v >> 24);
272     buf[index++] = (byte) ((v >> 16) & 0xff);
273     buf[index++] = (byte) ((v >> 8) & 0xff);
274     buf[index++] = (byte) (v & 0xff);
275     return index;
276   }
277
278
279   static int storeShort(byte buf[], int index, short v) {
280     buf[index++] = (byte) ((v >> 8) & 0xff);
281     buf[index++] = (byte) (v & 0xff);
282     return index;
283   }
284
285   static Insn read(InsnReadEnv insnEnv) {
286     boolean widen = false;
287     int pc = insnEnv.currentPC();
288
289     int op = insnEnv.getUByte();
290     if (op == opc_wide) {
291       widen = true;
292       op = insnEnv.getUByte();
293     }
294
295     switch (op) {
296     case opc_nop:
297     case opc_aconst_null:
298     case opc_iconst_m1:
299     case opc_iconst_0:
300     case opc_iconst_1:
301     case opc_iconst_2:
302     case opc_iconst_3:
303     case opc_iconst_4:
304     case opc_iconst_5:
305     case opc_lconst_0:
306     case opc_lconst_1:
307     case opc_fconst_0:
308     case opc_fconst_1:
309     case opc_fconst_2:
310     case opc_dconst_0:
311     case opc_dconst_1:
312     case opc_iload_0:
313     case opc_iload_1:
314     case opc_iload_2:
315     case opc_iload_3:
316     case opc_lload_0:
317     case opc_lload_1:
318     case opc_lload_2:
319     case opc_lload_3:
320     case opc_fload_0:
321     case opc_fload_1:
322     case opc_fload_2:
323     case opc_fload_3:
324     case opc_dload_0:
325     case opc_dload_1:
326     case opc_dload_2:
327     case opc_dload_3:
328     case opc_aload_0:
329     case opc_aload_1:
330     case opc_aload_2:
331     case opc_aload_3:
332     case opc_iaload:
333     case opc_laload:
334     case opc_faload:
335     case opc_daload:
336     case opc_aaload:
337     case opc_baload:
338     case opc_caload:
339     case opc_saload:
340     case opc_istore_0:
341     case opc_istore_1:
342     case opc_istore_2:
343     case opc_istore_3:
344     case opc_lstore_0:
345     case opc_lstore_1:
346     case opc_lstore_2:
347     case opc_lstore_3:
348     case opc_fstore_0:
349     case opc_fstore_1:
350     case opc_fstore_2:
351     case opc_fstore_3:
352     case opc_dstore_0:
353     case opc_dstore_1:
354     case opc_dstore_2:
355     case opc_dstore_3:
356     case opc_astore_0:
357     case opc_astore_1:
358     case opc_astore_2:
359     case opc_astore_3:
360     case opc_iastore:
361     case opc_lastore:
362     case opc_fastore:
363     case opc_dastore:
364     case opc_aastore:
365     case opc_bastore:
366     case opc_castore:
367     case opc_sastore:
368     case opc_pop:
369     case opc_pop2:
370     case opc_dup:
371     case opc_dup_x1:
372     case opc_dup_x2:
373     case opc_dup2:
374     case opc_dup2_x1:
375     case opc_dup2_x2:
376     case opc_swap:
377     case opc_iadd:
378     case opc_ladd:
379     case opc_fadd:
380     case opc_dadd:
381     case opc_isub:
382     case opc_lsub:
383     case opc_fsub:
384     case opc_dsub:
385     case opc_imul:
386     case opc_lmul:
387     case opc_fmul:
388     case opc_dmul:
389     case opc_idiv:
390     case opc_ldiv:
391     case opc_fdiv:
392     case opc_ddiv:
393     case opc_irem:
394     case opc_lrem:
395     case opc_frem:
396     case opc_drem:
397     case opc_ineg:
398     case opc_lneg:
399     case opc_fneg:
400     case opc_dneg:
401     case opc_ishl:
402     case opc_lshl:
403     case opc_ishr:
404     case opc_lshr:
405     case opc_iushr:
406     case opc_lushr:
407     case opc_iand:
408     case opc_land:
409     case opc_ior:
410     case opc_lor:
411     case opc_ixor:
412     case opc_lxor:
413     case opc_i2l:
414     case opc_i2f:
415     case opc_i2d:
416     case opc_l2i:
417     case opc_l2f:
418     case opc_l2d:
419     case opc_f2i:
420     case opc_f2l:
421     case opc_f2d:
422     case opc_d2i:
423     case opc_d2l:
424     case opc_d2f:
425     case opc_i2b:
426     case opc_i2c:
427     case opc_i2s:
428     case opc_lcmp:
429     case opc_fcmpl:
430     case opc_fcmpg:
431     case opc_dcmpl:
432     case opc_dcmpg:
433     case opc_ireturn:
434     case opc_lreturn:
435     case opc_freturn:
436     case opc_dreturn:
437     case opc_areturn:
438     case opc_return:
439     case opc_xxxunusedxxx:
440     case opc_arraylength:
441     case opc_athrow:
442     case opc_monitorenter:
443     case opc_monitorexit:
444       return new InsnSingle(op, pc);
445       
446     case opc_ldc:
447       return new InsnConstOp(op, insnEnv.pool().constantAt(insnEnv.getUByte()),
448                  pc);
449       
450     case opc_ldc_w:
451     case opc_ldc2_w:
452     case opc_getstatic:
453     case opc_putstatic:
454     case opc_getfield:
455     case opc_putfield:
456     case opc_invokevirtual:
457     case opc_invokespecial:
458     case opc_invokestatic:
459     case opc_new:
460     case opc_anewarray:
461     case opc_checkcast:
462     case opc_instanceof:
463       return new InsnConstOp(op,
464                  insnEnv.pool().constantAt(insnEnv.getUShort()),
465                  pc);
466       
467     case opc_iload:
468     case opc_lload:
469     case opc_fload:
470     case opc_dload:
471     case opc_aload:
472     case opc_istore:
473     case opc_lstore:
474     case opc_fstore:
475     case opc_dstore:
476     case opc_astore:
477     case opc_ret:
478       if (widen)
479     return new InsnIntOp(op, insnEnv.getShort(), pc);
480       else
481     return new InsnIntOp(op, insnEnv.getByte(), pc);
482
483     case opc_bipush: /* a byte constant */
484     case opc_newarray:
485       return new InsnIntOp(op, insnEnv.getByte(), pc);
486
487     case opc_sipush: /* a short constant */
488       return new InsnIntOp(op, insnEnv.getShort(), pc);
489
490     case opc_iinc:
491       if (widen)
492     return new InsnIInc(insnEnv.getUShort(), insnEnv.getShort(), pc);
493       else
494     return new InsnIInc(insnEnv.getUByte(), insnEnv.getByte(), pc);
495
496     case opc_ifeq:
497     case opc_ifne:
498     case opc_iflt:
499     case opc_ifge:
500     case opc_ifgt:
501     case opc_ifle:
502     case opc_if_icmpeq:
503     case opc_if_icmpne:
504     case opc_if_icmplt:
505     case opc_if_icmpge:
506     case opc_if_icmpgt:
507     case opc_if_icmple:
508     case opc_if_acmpeq:
509     case opc_if_acmpne:
510     case opc_goto:
511     case opc_jsr:
512     case opc_ifnull:
513     case opc_ifnonnull:
514       return new InsnTargetOp(op, insnEnv.getTarget(insnEnv.getShort()+pc), pc);
515
516     case opc_goto_w:
517     case opc_jsr_w:
518       return new InsnTargetOp(op, insnEnv.getTarget(insnEnv.getInt()+pc), pc);
519
520     case opc_tableswitch:
521       return InsnTableSwitch.read(insnEnv, pc);
522
523     case opc_lookupswitch:
524       return InsnLookupSwitch.read(insnEnv, pc);
525
526     case opc_invokeinterface:
527       return InsnInterfaceInvoke.read(insnEnv, pc);
528
529     case opc_multianewarray:
530       return InsnMultiDimArrayNew.read(insnEnv, pc);
531     }
532     throw new InsnError("Invalid byte code (" + op + ")");//NOI18N
533
}
534
535   /**
536    * Return the type of value manipulated by the load/store instruction
537    */

538   public static final int loadStoreDataType(int opcode) {
539     switch(opcode) {
540     case opc_iload:
541     case opc_iload_0:
542     case opc_iload_1:
543     case opc_iload_2:
544     case opc_iload_3:
545     case opc_istore:
546     case opc_istore_0:
547     case opc_istore_1:
548     case opc_istore_2:
549     case opc_istore_3:
550     case opc_iaload:
551     case opc_baload:
552     case opc_caload:
553     case opc_saload:
554     case opc_iastore:
555     case opc_bastore:
556     case opc_castore:
557     case opc_sastore:
558       return T_INT;
559
560     case opc_lload:
561     case opc_lload_0:
562     case opc_lload_1:
563     case opc_lload_2:
564     case opc_lload_3:
565     case opc_lstore:
566     case opc_lstore_0:
567     case opc_lstore_1:
568     case opc_lstore_2:
569     case opc_lstore_3:
570     case opc_laload:
571     case opc_lastore:
572       return T_LONG;
573
574     case opc_fload:
575     case opc_fload_0:
576     case opc_fload_1:
577     case opc_fload_2:
578     case opc_fload_3:
579     case opc_fstore:
580     case opc_fstore_0:
581     case opc_fstore_1:
582     case opc_fstore_2:
583     case opc_fstore_3:
584     case opc_faload:
585     case opc_fastore:
586       return T_FLOAT;
587
588     case opc_dload:
589     case opc_dload_0:
590     case opc_dload_1:
591     case opc_dload_2:
592     case opc_dload_3:
593     case opc_dstore:
594     case opc_dstore_0:
595     case opc_dstore_1:
596     case opc_dstore_2:
597     case opc_dstore_3:
598     case opc_daload:
599     case opc_dastore:
600       return T_DOUBLE;
601
602     case opc_aload:
603     case opc_aload_0:
604     case opc_aload_1:
605     case opc_aload_2:
606     case opc_aload_3:
607     case opc_astore:
608     case opc_astore_0:
609     case opc_astore_1:
610     case opc_astore_2:
611     case opc_astore_3:
612     case opc_aaload:
613     case opc_aastore:
614       return TC_OBJECT;
615
616     default:
617         throw new InsnError("not a load/store");//NOI18N
618
}
619   }
620 }
621
Popular Tags