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