1 package serp.bytecode;
2
3 import java.io.*;
4 import java.util.*;
5
6 import serp.bytecode.visitor.*;
7
8
9
10
11
12
13
14 public abstract class JumpInstruction extends Instruction
15 implements InstructionPtr {
16 private InstructionPtrStrategy _target = new InstructionPtrStrategy(this);
17
18 JumpInstruction(Code owner, int opcode) {
19 super(owner, opcode);
20 }
21
22
23
24
25 public Instruction getTarget() {
26 return _target.getTargetInstruction();
27 }
28
29
30
31
32
33
34
35 public JumpInstruction setTarget(Instruction instruction) {
36 _target.setTargetInstruction(instruction);
37 return this;
38 }
39
40
41
42
43
44
45 public boolean equalsInstruction(Instruction other) {
46 if (this == other)
47 return true;
48 if (!super.equalsInstruction(other))
49 return false;
50
51 Instruction target = ((JumpInstruction) other).getTarget();
52 return target == null || getTarget() == null || target == getTarget();
53 }
54
55 public void updateTargets() {
56 _target.updateTargets();
57 }
58
59 public void replaceTarget(Instruction oldTarget, Instruction newTarget) {
60 _target.replaceTarget(oldTarget, newTarget);
61 }
62
63 public void acceptVisit(BCVisitor visit) {
64 visit.enterJumpInstruction(this);
65 visit.exitJumpInstruction(this);
66 }
67
68 void read(Instruction orig) {
69 super.read(orig);
70 _target.setByteIndex(((JumpInstruction) orig)._target.getByteIndex());
71 }
72
73 void read(DataInput in) throws IOException {
74 super.read(in);
75 switch (getOpcode()) {
76 case Constants.GOTOW:
77 case Constants.JSRW:
78 _target.setByteIndex(getByteIndex() + in.readInt());
79 break;
80 default:
81 _target.setByteIndex(getByteIndex() + in.readShort());
82 }
83 }
84
85 void write(DataOutput out) throws IOException {
86 super.write(out);
87 switch (getOpcode()) {
88 case Constants.GOTOW:
89 case Constants.JSRW:
90 out.writeInt(_target.getByteIndex() - getByteIndex());
91 break;
92 default:
93 out.writeShort(_target.getByteIndex() - getByteIndex());
94 }
95 }
96
97 public void setOffset(int offset) {
98 _target.setByteIndex(getByteIndex() + offset);
99 }
100
101 public int getOffset() {
102 return _target.getByteIndex() - getByteIndex();
103 }
104 }