BranchHandle.java

  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. package org.apache.bcel.generic;

  18. /**
  19.  * BranchHandle is returned by specialized InstructionList.append() whenever a BranchInstruction is appended. This is
  20.  * useful when the target of this instruction is not known at time of creation and must be set later via setTarget().
  21.  *
  22.  * @see InstructionHandle
  23.  * @see Instruction
  24.  * @see InstructionList
  25.  */
  26. public final class BranchHandle extends InstructionHandle {

  27.     /**
  28.      * Factory method.
  29.      */
  30.     static BranchHandle getBranchHandle(final BranchInstruction i) {
  31.         return new BranchHandle(i);
  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.     private BranchHandle(final BranchInstruction i) {
  37.         super(i);
  38.         bi = i;
  39.     }

  40.     /*
  41.      * Override InstructionHandle methods: delegate to branch instruction. Through this overriding all access to the private
  42.      * i_position field should be prevented.
  43.      */
  44.     @Override
  45.     public int getPosition() {
  46.         return bi.getPosition();
  47.     }

  48.     /**
  49.      * @return target of instruction.
  50.      */
  51.     public InstructionHandle getTarget() {
  52.         return bi.getTarget();
  53.     }

  54.     /**
  55.      * Sets new contents. Old instruction is disposed and may not be used anymore.
  56.      */
  57.     @Override // This is only done in order to apply the additional type check; could be merged with super impl.
  58.     public void setInstruction(final Instruction i) { // TODO could be package-protected?
  59.         super.setInstruction(i);
  60.         if (!(i instanceof BranchInstruction)) {
  61.             throw new ClassGenException("Assigning " + i + " to branch handle which is not a branch instruction");
  62.         }
  63.         bi = (BranchInstruction) i;
  64.     }

  65.     @Override
  66.     void setPosition(final int pos) {
  67.         // Original code: i_position = bi.position = pos;
  68.         bi.setPosition(pos);
  69.         super.setPosition(pos);
  70.     }

  71.     /**
  72.      * Pass new target to instruction.
  73.      */
  74.     public void setTarget(final InstructionHandle ih) {
  75.         bi.setTarget(ih);
  76.     }

  77.     @Override
  78.     protected int updatePosition(final int offset, final int maxOffset) {
  79.         final int x = bi.updatePosition(offset, maxOffset);
  80.         super.setPosition(bi.getPosition());
  81.         return x;
  82.     }

  83.     /**
  84.      * Update target of instruction.
  85.      */
  86.     public void updateTarget(final InstructionHandle oldIh, final InstructionHandle newIh) {
  87.         bi.updateTarget(oldIh, newIh);
  88.     }
  89. }