21 package com.sun.org.apache.bcel.internal.generic; |
21 package com.sun.org.apache.bcel.internal.generic; |
22 |
22 |
23 /** |
23 /** |
24 * BranchHandle is returned by specialized InstructionList.append() whenever a |
24 * BranchHandle is returned by specialized InstructionList.append() whenever a |
25 * BranchInstruction is appended. This is useful when the target of this |
25 * BranchInstruction is appended. This is useful when the target of this |
26 * instruction is not known at time of creation and must be set later via |
26 * instruction is not known at time of creation and must be set later |
27 * setTarget(). |
27 * via setTarget(). |
28 * |
28 * |
29 * @see InstructionHandle |
29 * @see InstructionHandle |
30 * @see Instruction |
30 * @see Instruction |
31 * @see InstructionList |
31 * @see InstructionList |
32 * @version $Id: BranchHandle.java 1749603 2016-06-21 20:50:19Z ggregory $ |
32 * @version $Id$ |
33 */ |
33 */ |
34 public final class BranchHandle extends InstructionHandle { |
34 public final class BranchHandle extends InstructionHandle { |
35 |
35 |
36 // This is also a cache in case the InstructionHandle#swapInstruction() method is used |
36 // This is also a cache in case the InstructionHandle#swapInstruction() method is used |
37 // See BCEL-273 |
37 // See BCEL-273 |
38 private BranchInstruction bi; // An alias in fact, but saves lots of casts |
38 private BranchInstruction bi; // An alias in fact, but saves lots of casts |
39 |
39 |
|
40 |
40 private BranchHandle(final BranchInstruction i) { |
41 private BranchHandle(final BranchInstruction i) { |
41 super(i); |
42 super(i); |
42 bi = i; |
43 bi = i; |
43 } |
44 } |
44 |
45 |
45 /** |
46 /** Factory method. |
46 * Factory methods. |
|
47 */ |
47 */ |
48 private static BranchHandle bh_list = null; // List of reusable handles |
48 static BranchHandle getBranchHandle( final BranchInstruction i ) { |
49 |
49 return new BranchHandle(i); |
50 static BranchHandle getBranchHandle(final BranchInstruction i) { |
|
51 if (bh_list == null) { |
|
52 return new BranchHandle(i); |
|
53 } |
|
54 final BranchHandle bh = bh_list; |
|
55 bh_list = (BranchHandle) bh.getNext(); |
|
56 bh.setInstruction(i); |
|
57 return bh; |
|
58 } |
|
59 |
|
60 /** |
|
61 * Handle adds itself to the list of resuable handles. |
|
62 */ |
|
63 @Override |
|
64 protected void addHandle() { |
|
65 super.setNext(bh_list); |
|
66 bh_list = this; |
|
67 } |
50 } |
68 |
51 |
69 |
52 |
70 /* Override InstructionHandle methods: delegate to branch instruction. |
53 /* Override InstructionHandle methods: delegate to branch instruction. |
71 * Through this overriding all access to the private i_position field should |
54 * Through this overriding all access to the private i_position field should |
74 @Override |
57 @Override |
75 public int getPosition() { |
58 public int getPosition() { |
76 return bi.getPosition(); |
59 return bi.getPosition(); |
77 } |
60 } |
78 |
61 |
|
62 |
79 @Override |
63 @Override |
80 void setPosition(final int pos) { |
64 void setPosition( final int pos ) { |
81 // Original code: i_position = bi.position = pos; |
65 // Original code: i_position = bi.position = pos; |
82 bi.setPosition(pos); |
66 bi.setPosition(pos); |
83 super.setPosition(pos); |
67 super.setPosition(pos); |
84 } |
68 } |
85 |
69 |
|
70 |
86 @Override |
71 @Override |
87 protected int updatePosition(final int offset, final int max_offset) { |
72 protected int updatePosition( final int offset, final int max_offset ) { |
88 final int x = bi.updatePosition(offset, max_offset); |
73 final int x = bi.updatePosition(offset, max_offset); |
89 super.setPosition(bi.getPosition()); |
74 super.setPosition(bi.getPosition()); |
90 return x; |
75 return x; |
91 } |
76 } |
92 |
77 |
|
78 |
93 /** |
79 /** |
94 * Pass new target to instruction. |
80 * Pass new target to instruction. |
95 */ |
81 */ |
96 public void setTarget(final InstructionHandle ih) { |
82 public void setTarget( final InstructionHandle ih ) { |
97 bi.setTarget(ih); |
83 bi.setTarget(ih); |
98 } |
84 } |
|
85 |
99 |
86 |
100 /** |
87 /** |
101 * Update target of instruction. |
88 * Update target of instruction. |
102 */ |
89 */ |
103 public void updateTarget(final InstructionHandle old_ih, final InstructionHandle new_ih) { |
90 public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) { |
104 bi.updateTarget(old_ih, new_ih); |
91 bi.updateTarget(old_ih, new_ih); |
105 } |
92 } |
|
93 |
106 |
94 |
107 /** |
95 /** |
108 * @return target of instruction. |
96 * @return target of instruction. |
109 */ |
97 */ |
110 public InstructionHandle getTarget() { |
98 public InstructionHandle getTarget() { |
111 return bi.getTarget(); |
99 return bi.getTarget(); |
112 } |
100 } |
113 |
101 |
|
102 |
114 /** |
103 /** |
115 * Set new contents. Old instruction is disposed and may not be used |
104 * Set new contents. Old instruction is disposed and may not be used anymore. |
116 * anymore. |
|
117 */ |
105 */ |
118 @Override // This is only done in order to apply the additional type check; could be merged with super impl. |
106 @Override // This is only done in order to apply the additional type check; could be merged with super impl. |
119 public void setInstruction(final Instruction i) { // TODO could be package-protected? |
107 public void setInstruction( final Instruction i ) { // TODO could be package-protected? |
120 super.setInstruction(i); |
108 super.setInstruction(i); |
121 if (!(i instanceof BranchInstruction)) { |
109 if (!(i instanceof BranchInstruction)) { |
122 throw new ClassGenException("Assigning " + i |
110 throw new ClassGenException("Assigning " + i |
123 + " to branch handle which is not a branch instruction"); |
111 + " to branch handle which is not a branch instruction"); |
124 } |
112 } |