View Javadoc

1   package serp.bytecode;
2   
3   import java.io.*;
4   import java.util.*;
5   
6   import serp.bytecode.lowlevel.*;
7   import serp.bytecode.visitor.*;
8   
9   /***
10   * A line number corresponds to a sequence of opcodes that map logically
11   * to a line of source code.
12   *
13   * @author Abe White
14   */
15  public class LineNumber implements Comparable, InstructionPtr, BCEntity,
16      VisitAcceptor {
17      private int _line = 0;
18      private LineNumberTable _owner = null;
19      InstructionPtrStrategy _target = new InstructionPtrStrategy(this);
20  
21      LineNumber(LineNumberTable owner) {
22          _owner = owner;
23      }
24  
25      LineNumber(LineNumberTable owner, int startPc) {
26          this(owner);
27          setStartPc(startPc);
28      }
29  
30      /***
31       * Line numbers are stored in a {@link LineNumberTable}.
32       */
33      public LineNumberTable getTable() {
34          return _owner;
35      }
36  
37      void invalidate() {
38          _owner = null;
39      }
40  
41      /***
42       * Return source line number.
43       */
44      public int getLine() {
45          return _line;
46      }
47  
48      /***
49       * Set the source line number.
50       */
51      public void setLine(int lineNumber) {
52          _line = lineNumber;
53      }
54  
55      /***
56       * Return the instruction marking the beginning of this line.
57       */
58      public Instruction getStart() {
59          return _target.getTargetInstruction();
60      }
61  
62      /***
63       * Return the index into the code byte array at which this line starts.
64       */
65      public int getStartPc() {
66          return _target.getByteIndex();
67      }
68  
69      /***
70       * Set the index into the code byte array at which this line starts.
71       */
72      public void setStartPc(int startPc) {
73          _target.setByteIndex(startPc);
74      }
75  
76      /***
77       * Set the {@link Instruction} marking the beginning this line.
78       * The instruction must already be a part of the method.
79       */
80      public void setStart(Instruction instruction) {
81          _target.setTargetInstruction(instruction);
82      }
83  
84      public void updateTargets() {
85          _target.updateTargets();
86      }
87  
88      public void replaceTarget(Instruction oldTarget, Instruction newTarget) {
89          _target.replaceTarget(oldTarget, newTarget);
90      }
91  
92      public Project getProject() {
93          return _owner.getProject();
94      }
95  
96      public ConstantPool getPool() {
97          return _owner.getPool();
98      }
99  
100     public ClassLoader getClassLoader() {
101         return _owner.getClassLoader();
102     }
103 
104     public boolean isValid() {
105         return _owner != null;
106     }
107 
108     public void acceptVisit(BCVisitor visit) {
109         visit.enterLineNumber(this);
110         visit.exitLineNumber(this);
111     }
112 
113     public int compareTo(Object other) {
114         if (!(other instanceof LineNumber))
115             return -1;
116 
117         LineNumber ln = (LineNumber) other;
118         if (getStartPc() == ln.getStartPc())
119             return 0;
120         if (getStartPc() < ln.getStartPc())
121             return -1;
122         return 1;
123     }
124 
125     void read(DataInput in) throws IOException {
126         setStartPc(in.readUnsignedShort());
127         setLine(in.readUnsignedShort());
128     }
129 
130     void write(DataOutput out) throws IOException {
131         out.writeShort(getStartPc());
132         out.writeShort(getLine());
133     }
134 
135     public Code getCode() {
136         return _owner.getCode();
137     }
138 }