• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  */
18 package org.apache.bcel.generic;
19 
20 /**
21  * BranchHandle is returned by specialized InstructionList.append() whenever a
22  * BranchInstruction is appended. This is useful when the target of this
23  * instruction is not known at time of creation and must be set later
24  * via setTarget().
25  *
26  * @see InstructionHandle
27  * @see Instruction
28  * @see InstructionList
29  * @version $Id$
30  */
31 public final class BranchHandle extends InstructionHandle {
32 
33     // This is also a cache in case the InstructionHandle#swapInstruction() method is used
34     // See BCEL-273
35     private BranchInstruction bi; // An alias in fact, but saves lots of casts
36 
37 
BranchHandle(final BranchInstruction i)38     private BranchHandle(final BranchInstruction i) {
39         super(i);
40         bi = i;
41     }
42 
43     /** Factory methods.
44      */
45     private static BranchHandle bh_list = null; // List of reusable handles
46 
47 
getBranchHandle( final BranchInstruction i )48     static BranchHandle getBranchHandle( final BranchInstruction i ) {
49         if (bh_list == null) {
50             return new BranchHandle(i);
51         }
52         final BranchHandle bh = bh_list;
53         bh_list = (BranchHandle) bh.getNext();
54         bh.setInstruction(i);
55         return bh;
56     }
57 
58 
59     /** Handle adds itself to the list of resuable handles.
60      */
61     @Override
addHandle()62     protected void addHandle() {
63         super.setNext(bh_list);
64         bh_list = this;
65     }
66 
67 
68     /* Override InstructionHandle methods: delegate to branch instruction.
69      * Through this overriding all access to the private i_position field should
70      * be prevented.
71      */
72     @Override
getPosition()73     public int getPosition() {
74         return bi.getPosition();
75     }
76 
77 
78     @Override
setPosition( final int pos )79     void setPosition( final int pos ) {
80         // Original code: i_position = bi.position = pos;
81         bi.setPosition(pos);
82         super.setPosition(pos);
83     }
84 
85 
86     @Override
updatePosition( final int offset, final int max_offset )87     protected int updatePosition( final int offset, final int max_offset ) {
88         final int x = bi.updatePosition(offset, max_offset);
89         super.setPosition(bi.getPosition());
90         return x;
91     }
92 
93 
94     /**
95      * Pass new target to instruction.
96      */
setTarget( final InstructionHandle ih )97     public void setTarget( final InstructionHandle ih ) {
98         bi.setTarget(ih);
99     }
100 
101 
102     /**
103      * Update target of instruction.
104      */
updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih )105     public void updateTarget( final InstructionHandle old_ih, final InstructionHandle new_ih ) {
106         bi.updateTarget(old_ih, new_ih);
107     }
108 
109 
110     /**
111      * @return target of instruction.
112      */
getTarget()113     public InstructionHandle getTarget() {
114         return bi.getTarget();
115     }
116 
117 
118     /**
119      * Set new contents. Old instruction is disposed and may not be used anymore.
120      */
121     @Override // This is only done in order to apply the additional type check; could be merged with super impl.
setInstruction( final Instruction i )122     public void setInstruction( final Instruction i ) { // TODO could be package-protected?
123         super.setInstruction(i);
124         if (!(i instanceof BranchInstruction)) {
125             throw new ClassGenException("Assigning " + i
126                     + " to branch handle which is not a branch instruction");
127         }
128         bi = (BranchInstruction) i;
129     }
130 }
131