Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/techtrader/modules/tools/bytecode/StackInstruction.java


1   package com.techtrader.modules.tools.bytecode;
2   
3   
4   import com.techtrader.modules.tools.bytecode.visitor.BCVisitor;
5   
6   
7   /**
8    *  Represents an instruction that manipulates the stack of the current
9    *  frame.  Using the setType methods is a hint about the type being 
10   *  manipulated that might cause this Instruction to use the wide version 
11   *  of the opcode it represents (if manipulating a long or double).  This
12   *  saves the developer from having to decide at compile time whether to
13   *  use pop() or pop2(), etc.
14   *
15   *  @author    Abe White
16   */
17  public class StackInstruction
18    extends Instruction
19  {
20    protected StackInstruction (Code owner, int opcode)
21    {
22      super (owner);
23      _opcode = opcode;
24    }
25  
26  
27    /**
28     *  Set the type that is being manipulated; this might cause the
29     *  instruction to change to the wide version of the opcode it represents.
30     *
31     *  @return  this Instruction, for method chaining
32     */
33    public StackInstruction setType (Class type)
34    {
35      boolean wide = type.equals (long.class) || type.equals (double.class);
36      calculateOpCode (wide);
37      return this;
38    }
39  
40  
41    /**
42     *  Set the type to manipulate by name.
43     *
44     *  @return  this Instruction, for method chaining
45     *  
46     *  @see  #setType(java.lang.Class)
47     */
48    public StackInstruction setTypeName (String name)
49    {
50      boolean wide = name.equals ("long") || name.equals ("double");
51      calculateOpCode (wide);
52      return this;
53    }
54  
55  
56    public int getStackChange ()
57    {
58      switch (_opcode)
59      {
60      case POP:
61        return -1;
62  
63      case POP2:
64        return -2;
65  
66      case DUP:
67      case DUP_X1:
68      case DUP_X2:
69        return 1;
70  
71      case DUP2:
72      case DUP2_X1:
73      case DUP2_X2:
74        return 2;
75  
76      default:
77        return 0;
78      }
79    }
80  
81  
82    /**
83     *  Helper method to change the opcode of this instruction if need be.
84     */
85    private void calculateOpCode (boolean wide)
86    {
87      switch (_opcode)
88      {
89      case POP:
90        if (wide) _opcode = POP2;
91        break;
92      case POP2:
93        if (!wide) _opcode = POP;
94        break;
95      case DUP:
96        if (wide) _opcode = DUP2;
97        break;
98      case DUP2:
99        if (!wide) _opcode = DUP;
100       break;
101     case DUP_X1:
102       if (wide) _opcode = DUP2_X1;
103       break;
104     case DUP2_X1:
105       if (!wide) _opcode = DUP_X1;
106       break;
107     case DUP_X2:
108       if (wide) _opcode = DUP2_X2;
109       break;
110     case DUP2_X2:
111       if (!wide) _opcode = DUP_X2;
112       break;
113     }
114   }
115 
116 
117   public void acceptVisit (BCVisitor visit)
118   {
119     visit.enterStackInstruction (this);
120     visit.exitStackInstruction (this);
121   }
122 }