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/CmpInstruction.java


1   package com.techtrader.modules.tools.bytecode;
2   
3   
4   import com.techtrader.modules.tools.bytecode.visitor.BCVisitor;
5   
6   
7   /**
8    *  An instruction comparing two stack values that varies depending on the
9    *  value type.
10   *
11   *  @author    Abe White
12   */
13  public class CmpInstruction
14    extends Instruction
15  {
16    private Class   _type   = null;
17    private int    _nan  = -1;  
18  
19  
20    protected CmpInstruction (Code owner)
21    {
22      super (owner);
23    }
24  
25  
26    protected CmpInstruction (Code owner, int opcode, Class type, int nan)
27    {
28      super (owner);
29      _opcode = opcode;
30      _type = type;
31      _nan = nan;
32    }
33  
34  
35    /**
36     *  Get the type of value to operate on; this is one of:
37     *  float, double, long.
38     */
39    public Class getType ()
40    {
41      return _type;
42    }
43  
44  
45    /**
46     *  Get the type of value to operate on; this is one of:
47     *  float, double, long.
48     */
49    public String getTypeName ()
50    {
51      if (_type == null)
52        return null;
53  
54      return _type.getName ();
55    }
56  
57  
58    /**
59     *  Set the type of value to operate on; primitives that have no direct
60     *  support (byte, char, boolean, int) will be conerted to long.class.
61     *
62     *  @return    this Instruction, for method chaining
63     */
64    public CmpInstruction setType (Class type)
65    {
66      if (float.class.equals (type))
67        _type = float.class;
68      else if (double.class.equals (type))
69        _type = double.class;
70      else
71        _type = long.class;
72      
73      calculateOpCode ();
74      return this;
75    }
76  
77  
78    /**
79     *  Set the type to load by name.
80     *
81     *  @return    this Instruction, for method chaining
82     *  
83     *  @see  #setType(java.lang.Class)
84     */
85    public CmpInstruction setTypeName (String name)
86    {
87      if ("float".equals (name))
88        _type = float.class;
89      else if ("double".equals (name))
90        _type = double.class;
91      else
92        _type = long.class;
93  
94      calculateOpCode ();
95      return this;
96    }
97  
98  
99    /**
100    *  Get the number that will be placed on the stack if this instruction
101    *  is of type float or double and one of the operands is NaN.  The
102    *  return value will be either 1 or -1.
103    */
104   public int getNaNValue ()
105   {
106     if (_type == null || _type.equals (long.class))
107       return 0;
108 
109     return _nan;
110   }
111   
112 
113   /**
114    *  Set the number that will be placed on the stack if this instruction
115    *  is of type float or double and one of the operands is NaN.  The
116    *  value must be either 1 or -1.
117    */
118   public void setNaNValue (int nan)
119   {
120     _nan = nan;
121   }
122 
123 
124   
125   /**
126    *  Two cmp instructions are equal if the type and NaN value they
127    *  reference is equal or the type of either instruction is unset.
128    */
129   public boolean equals (Object other)
130   {
131     if (this == other)
132       return true;
133     if (!(other instanceof CmpInstruction))
134       return false;
135     if (!super.equals (other))
136       return false;
137 
138     CmpInstruction ins = (CmpInstruction) other;
139     if (_type == null || ins._type == null)
140       return true;
141 
142 
143     return _type.equals (ins._type) && _nan == ins._nan;
144   }
145 
146 
147   public int getStackChange ()
148   {
149     if (_type.equals (long.class) || _type.equals (double.class))
150       return -3;
151 
152     return -1;
153   }
154 
155 
156   public void acceptVisit (BCVisitor visit)
157   {
158     visit.enterCmpInstruction (this);
159     visit.exitCmpInstruction (this);
160   }
161 
162 
163   protected void copy (Instruction orig)
164   {
165     super.copy (orig);
166 
167     CmpInstruction ins = (CmpInstruction) orig;
168     _type = ins._type;
169     _nan = ins._nan;
170   }
171 
172 
173   private void calculateOpCode ()
174   {
175     if (_type.equals (long.class))
176       _opcode = LCMP;
177     else if (_type.equals (float.class))
178       _opcode = (_nan == 1) ? FCMPG : FCMPL;
179     else
180       _opcode = (_nan == 1) ? DCMPG : DCMPL;
181   }
182 }