View Javadoc

1   package serp.bytecode;
2   
3   /***
4    * InstructionPtrStrategy handles the different strategies for finding the
5    * Instructions that InstructionPtrs point to. These strategies include,
6    * from least desirable to most desirable, using byte indexes,
7    * and storing a reference to the target Instruction proper.
8    *
9    * @author Eric Lindauer
10   * @date 2002.7.26
11   */
12  class InstructionPtrStrategy implements InstructionPtr {
13      // the Instruction doing the targetting
14      private InstructionPtr _pointer;
15  
16      // two different ways to find the target from the pointer.
17      // _target is used first, then _byteIndex
18      private Instruction _target = null;
19      private int _byteIndex = -1;
20  
21      public InstructionPtrStrategy(InstructionPtr pointer) {
22          _pointer = pointer;
23      }
24  
25      public InstructionPtrStrategy(InstructionPtr pointer, Instruction target) {
26          this(pointer);
27          setTargetInstruction(target);
28      }
29  
30      /***
31       * Sets the byteIndex where the target Instruction can be found.
32       * This target will now be using byte indices as its target finding
33       * strategy, which is the least robust option. Changing the Code block
34       * or importing it into another Method may result in an invalid target.
35       */
36      public void setByteIndex(int index) {
37          if (index < -1)
38              throw new IllegalArgumentException(String.valueOf(index));
39          _byteIndex = index;
40          _target = null;
41      }
42  
43      /***
44       * Changes the target Instruction. The target is in the best state
45       * possible and should maintain this information even in the face
46       * of Code imports and Code changes.
47       */
48      public void setTargetInstruction(Instruction ins) {
49          if (ins.getCode() != getCode())
50              throw new IllegalArgumentException("Instruction pointers and " 
51                  + "targets must be part of the same code block.");
52          _target = ins;
53          _byteIndex = -1;
54      }
55  
56      /***
57       * Returns the Instruction this Target is targetting. This request
58       * does not change the targetting strategy for this Target.
59       */
60      public Instruction getTargetInstruction() {
61          if (_target != null)
62              return _target;
63          return getCode().getInstruction(_byteIndex);
64      }
65  
66      /***
67       * Returns the byteIndex at which the target instruction can be found.
68       * This call does not change the Target strategy.
69       */
70      public int getByteIndex() {
71          if (_target == null)
72              return _byteIndex;
73          return _target.getByteIndex();
74      }
75  
76      /***
77       * Same as getInstruction, but this method alters the Target strategy
78       * to use the returned Instruction. This method alters the Target
79       * strategy (and Instruction) iff it was previously using byte indexes.
80       */
81      public void updateTargets() {
82          if (_target == null)
83              _target = getCode().getInstruction(_byteIndex);
84      }
85  
86      public void replaceTarget(Instruction oldTarget, Instruction newTarget) {
87          if (getTargetInstruction() == oldTarget)
88              setTargetInstruction(newTarget);
89      }
90  
91      public Code getCode() {
92          return _pointer.getCode();
93      }
94  }