View Javadoc

1   package serp.bytecode;
2   
3   import java.io.*;
4   
5   import serp.bytecode.lowlevel.*;
6   import serp.bytecode.visitor.*;
7   
8   /***
9    * An instruction that takes as an argument a class to operate
10   * on. Examples include <code>anewarray, checkcast, instance, anew</code>, etc.
11   *
12   * @author Abe White
13   */
14  public class ClassInstruction extends TypedInstruction {
15      private int _index = 0;
16  
17      ClassInstruction(Code owner, int opcode) {
18          super(owner, opcode);
19      }
20  
21      public int getStackChange() {
22          if (getOpcode() == Constants.NEW)
23              return 1;
24          return 0;
25      }
26  
27      int getLength() {
28          return super.getLength() + 2;
29      }
30  
31      /***
32       * Return the {@link ConstantPool} index of the
33       * {@link ClassEntry} describing the class for this instruction.
34       */
35      public int getTypeIndex() {
36          return _index;
37      }
38  
39      /***
40       * Set the {@link ConstantPool} index of the
41       * {@link ClassEntry} describing the class for this instruction.
42       *
43       * @return this instruction, for method chaining
44       */
45      public ClassInstruction setTypeIndex(int index) {
46          _index = index;
47          return this;
48      }
49  
50      public String getTypeName() {
51          if (_index == 0)
52              return null;
53  
54          ClassEntry entry = (ClassEntry) getPool().getEntry(_index);
55          return getProject().getNameCache().getExternalForm(entry.
56              getNameEntry().getValue(), false);
57      }
58  
59      public TypedInstruction setType(String type) {
60          if (type == null)
61              _index = 0;
62          else {
63              type = getProject().getNameCache().getInternalForm(type, false);
64              _index = getPool().findClassEntry(type, true);
65          }
66          return this;
67      }
68  
69      /***
70       * ClassInstructions are equal if the type they reference is the same or
71       * unset and if their opcodes are equal.
72       */
73      public boolean equalsInstruction(Instruction other) {
74          if (other == this)
75              return true;
76          if (!super.equalsInstruction(other))
77              return false;
78  
79          String type = getTypeName();
80          String otherType = ((ClassInstruction) other).getTypeName();
81          return (type == null) || (otherType == null) || type.equals(otherType);
82      }
83  
84      public void acceptVisit(BCVisitor visit) {
85          visit.enterClassInstruction(this);
86          visit.exitClassInstruction(this);
87      }
88  
89      void read(Instruction other) {
90          super.read(other);
91          setType(((ClassInstruction) other).getTypeName());
92      }
93  
94      void read(DataInput in) throws IOException {
95          super.read(in);
96          _index = in.readUnsignedShort();
97      }
98  
99      void write(DataOutput out) throws IOException {
100         super.write(out);
101         out.writeShort(_index);
102     }
103 }