View Javadoc

1   package serp.bytecode;
2   
3   import java.io.*;
4   import java.util.*;
5   
6   import serp.bytecode.visitor.*;
7   
8   /***
9    * The <code>newarray</code> instruction, which is used to create new
10   * arrays of primitive types.
11   *
12   * @author Abe White
13   */
14  public class NewArrayInstruction extends TypedInstruction {
15      private static final Class[][] _mappings = new Class[][] {
16          { void.class, int.class },
17          { Object.class, int.class },
18      };
19      private int _code = -1;
20  
21      NewArrayInstruction(Code owner) {
22          super(owner, Constants.NEWARRAY);
23      }
24  
25      int getLength() {
26          return super.getLength() + 1;
27      }
28  
29      public String getTypeName() {
30          switch (getTypeCode()) {
31          case Constants.ARRAY_BOOLEAN:
32              return boolean.class.getName();
33          case Constants.ARRAY_CHAR:
34              return char.class.getName();
35          case Constants.ARRAY_FLOAT:
36              return float.class.getName();
37          case Constants.ARRAY_DOUBLE:
38              return double.class.getName();
39          case Constants.ARRAY_BYTE:
40              return byte.class.getName();
41          case Constants.ARRAY_SHORT:
42              return short.class.getName();
43          case Constants.ARRAY_INT:
44              return int.class.getName();
45          case Constants.ARRAY_LONG:
46              return long.class.getName();
47          default:
48              return null;
49          }
50      }
51  
52      public TypedInstruction setType(String type) {
53          type = mapType(type, _mappings, true);
54          if (type == null)
55              return setTypeCode(-1);
56  
57          switch (type.charAt(0)) {
58          case 'b':
59              if (boolean.class.getName().equals(type))
60                  return setTypeCode(Constants.ARRAY_BOOLEAN);
61              return setTypeCode(Constants.ARRAY_BYTE);
62          case 'c':
63              return setTypeCode(Constants.ARRAY_CHAR);
64          case 'f':
65              return setTypeCode(Constants.ARRAY_FLOAT);
66          case 'd':
67              return setTypeCode(Constants.ARRAY_DOUBLE);
68          case 's':
69              return setTypeCode(Constants.ARRAY_SHORT);
70          case 'i':
71              return setTypeCode(Constants.ARRAY_INT);
72          case 'l':
73              return setTypeCode(Constants.ARRAY_LONG);
74          default:
75              throw new IllegalStateException();
76          }
77      }
78  
79      /***
80       * Return the array code used in the lowlevel bytecode, or -1 if unset.
81       */
82      public int getTypeCode() {
83          return _code;
84      }
85  
86      /***
87       * Set the array code used in the lowlevel bytecode.
88       *
89       * @return this instruction, for method chaining
90       */
91      public NewArrayInstruction setTypeCode(int code) {
92          _code = code;
93          return this;
94      }
95  
96      /***
97       * NewArray instructions are equal if the array type is the same,
98       * of if the array type of either is unset.
99       */
100     public boolean equalsInstruction(Instruction other) {
101         if (this == other)
102             return true;
103         if (!(other instanceof NewArrayInstruction))
104             return false;
105 
106         NewArrayInstruction ins = (NewArrayInstruction) other;
107         int code = getTypeCode();
108         int otherCode = ins.getTypeCode();
109         return code == -1 || otherCode == -1 || code == otherCode;
110     }
111 
112     public void acceptVisit(BCVisitor visit) {
113         visit.enterNewArrayInstruction(this);
114         visit.exitNewArrayInstruction(this);
115     }
116 
117     void read(Instruction orig) {
118         super.read(orig);
119         _code = ((NewArrayInstruction) orig).getTypeCode();
120     }
121 
122     void read(DataInput in) throws IOException {
123         super.read(in);
124         _code = in.readUnsignedByte();
125     }
126 
127     void write(DataOutput out) throws IOException {
128         super.write(out);
129         out.writeByte(_code);
130     }
131 }