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


1   package com.techtrader.modules.tools.bytecode;
2   
3   
4   import java.util.Map;
5   import java.util.HashMap;
6   
7   import com.techtrader.modules.tools.bytecode.visitor.BCVisitor;
8   
9   
10  /**
11   *  Represents one of the math operations defined in the 
12   *  {@link Constants} interface.  
13   *  Changing the type or operation of the instruction will automatically
14   *  update the underlying opcode.  Note, however, that some operations
15   *  cannot act on floating point types.
16   *
17   *  @author    Abe White
18   */
19  public class MathInstruction
20    extends Instruction
21  {
22    private static final Map _typeNames = new HashMap ();
23    static
24    {
25      _typeNames.put ("long", long.class);
26      _typeNames.put ("float", float.class);
27      _typeNames.put ("double", double.class);
28    }
29  
30    private Class  _type    = null;
31    private int    _operation  = -1;
32  
33  
34    protected MathInstruction (Code owner)
35    {
36      super (owner);
37    }
38  
39  
40    protected MathInstruction (Code owner, int opcode, int operation, 
41      Class type)
42    {
43      super (owner);
44      _opcode = opcode;
45      _operation = operation;
46      _type = type;
47    }
48  
49  
50    /**
51      *  Set the math operation to be performed.  This should be one of the
52     *  math constant defined in {@link Constants}.
53      *  
54     *  @return    this Instruction, for method chaining
55     */
56    public MathInstruction setOperation (int operation)
57    {
58      _operation = operation;
59      calculateOpCode ();
60      return this;
61    }
62  
63  
64    /**
65      *  Return the operation for this math instruction; will be one of the
66     *  math constant defined in {@link Constants}, or -1 if
67      *  unset.
68     */
69    public int getOperation ()
70    {
71      return _operation;
72    }
73  
74  
75    /**
76     *  Get the type of args to operation on; will be one of:
77     *  int, float, double, long.
78     *  If the type has not been set, this method will return null.
79     */
80    public Class getType ()
81    {
82      return _type;
83    }
84  
85  
86    /**
87     *  Set the type of args to operate on.  Types without direct support are
88     *  demoted to int.class.
89     *
90     *  @return  this Instruction, for method chaining
91     */
92    public MathInstruction setType (Class type)
93    {
94      if (float.class.equals (type) || double.class.equals (type)
95        || long.class.equals (type))
96        _type = type;
97      else
98        _type = int.class;
99      
100     calculateOpCode ();
101     return this;
102   }
103 
104 
105   /**
106    *  Set the type to load by name.
107    *
108    *  @return  this Instruction, for method chaining
109    *  
110    *  @see  #setType(java.lang.Class)
111    */
112   public MathInstruction setTypeName (String name)
113   {
114     _type = (Class) _typeNames.get (name);
115     if (_type == null && name != null)
116       _type = int.class;
117 
118     calculateOpCode ();
119     return this;
120   }
121 
122 
123   /**
124    *  MathInstructions are equal if they have the same operation and type,
125    *  or the type of either is unset.
126    */
127   public boolean equals (Object other)
128   {
129     if (this == other)
130       return true;
131     if (!(other instanceof MathInstruction))
132       return false;
133 
134     MathInstruction ins = (MathInstruction) other;
135 
136     boolean opEq = (_operation == -1 || ins._operation == -1
137       || _operation == ins._operation);
138     boolean typeEq = (_type == null || ins._type == null
139       || _type.equals (ins._type));
140 
141     return opEq && typeEq;
142   }
143 
144 
145   public int getStackChange ()
146   {
147     if (_operation == MATH_NEG)
148       return 0;
149 
150     if (_type.equals (long.class) || _type.equals (double.class))
151       return -2;
152 
153     return -1;
154   }
155 
156 
157   protected void copy (Instruction orig)
158   {
159     super.copy (orig);
160 
161     MathInstruction mi = (MathInstruction) orig;
162     _type = mi._type;
163     _operation = mi._operation;
164   }
165 
166 
167   /**
168    *  Helper method to calculate the correct opcode for this instruction.
169    *  Takes advantage of the arrangements of the opcodes and constants.
170    */
171   private void calculateOpCode ()
172   {
173     _opcode = _operation + _opcodeTypes.indexOf (_type);
174   }
175 
176 
177   public void acceptVisit (BCVisitor visit)
178   {
179     visit.enterMathInstruction (this);
180     visit.exitMathInstruction (this);
181   }
182 }