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 }