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